compare

compare(a: ET.Element, b: ET.Element)

The differences between two canonical forms (from canonicalize): the header, the part list, and measure by measure the items only one of them has.

>>> import io
>>> from openmusickit.io.musicxml.container import load
>>> def score(step: bytes):
...     return canonicalize(load(io.BytesIO(b'<score-partwise><part-list><score-part id="P1">'
...         b'<part-name>Fl</part-name></score-part></part-list><part id="P1"><measure number="1">'
...         b'<attributes><divisions>1</divisions></attributes><note><pitch><step>' + step
...         + b'</step><octave>4</octave></pitch><duration>4</duration><type>whole</type></note>'
...         b'</measure></part></score-partwise>')))
>>> [(d.kind, d.measure, d.detail) for d in compare(score(b"C"), score(b"D"))]
[('note', 1, '- <note at="0" staff="1" voice="1" pitch="C4" duration="1" type="whole" />'), ('note', 1, '+ <note at="0" staff="1" voice="1" pitch="D4" duration="1" type="whole" />')]