When a slur has bezier control points on both its start and stop elements in MusicXML, parsing only keeps the stop element's values, the start element's bezier-x/bezier-y get silently overwritten instead of landing in the (separately named) bezierX2/bezierY2 slots.
Repro:
import music21
xml = '''<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 4.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="4.0">
<part-list><score-part id="P1"><part-name>Music</part-name></score-part></part-list>
<part id="P1">
<measure number="1">
<attributes>
<divisions>1</divisions>
<time><beats>2</beats><beat-type>4</beat-type></time>
<clef><sign>G</sign><line>2</line></clef>
</attributes>
<note>
<pitch><step>C</step><octave>5</octave></pitch>
<duration>1</duration><type>quarter</type>
<notations><slur number="1" type="start" bezier-x="11" bezier-y="-22"/></notations>
</note>
<note>
<pitch><step>D</step><octave>5</octave></pitch>
<duration>1</duration><type>quarter</type>
<notations><slur number="1" type="stop" bezier-x="-33" bezier-y="44"/></notations>
</note>
</measure>
</part>
</score-partwise>'''
slur = music21.converter.parse(xml, format="musicxml").recurse().getElementsByClass(music21.spanner.Slur)[0]
print(slur.style.bezierX, slur.style.bezierY) # -33 44 -- should be 11 -22, the START tag's own values
Looks like it's coming from xmlNotationsToSpanners in musicxml/xmlToM21.py, it calls setStyleAttributes once per element found, writing into bezierX/bezierY regardless of whether the element is the start or the stop tag, so whichever one gets processed second wins. The bezier-x2/bezier-y2 attribute names exist and would land in the right slot, but nothing ever routes the stop element's own bezier attributes there.
When a slur has bezier control points on both its start and stop elements in MusicXML, parsing only keeps the stop element's values, the start element's bezier-x/bezier-y get silently overwritten instead of landing in the (separately named) bezierX2/bezierY2 slots.
Repro:
Looks like it's coming from xmlNotationsToSpanners in musicxml/xmlToM21.py, it calls setStyleAttributes once per element found, writing into bezierX/bezierY regardless of whether the element is the start or the stop tag, so whichever one gets processed second wins. The bezier-x2/bezier-y2 attribute names exist and would land in the right slot, but nothing ever routes the stop element's own bezier attributes there.