Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
25 changes: 20 additions & 5 deletions audit/classify.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class in O(n), fully reorder-invariant. See
D enum-bug text/attr value is a known missing enum member
E missing-attribute a partial feature's attribute was dropped
F pipeline-error LOADFAIL / GETDATAFAIL / CREATEFAIL (no actual produced)
G supported-drop a dropped element class is marked support="full"/"partial"
(an impl round-trip bug or an api.features.xml overstatement)
unknown a FAIL that matched none of the above
"""

Expand Down Expand Up @@ -56,11 +58,12 @@ class in O(n), fully reorder-invariant. See
"D": "enum bug",
"E": "missing attribute/element",
"F": "pipeline error",
"G": "supported-element drop",
"unknown": "unknown",
}

# Categories that are actionable feature gaps (ranked in the worklist).
_ACTIONABLE = frozenset({"B", "D", "E"})
_ACTIONABLE = frozenset({"B", "D", "E", "G"})


# --------------------------------------------------------------------------- #
Expand Down Expand Up @@ -375,8 +378,18 @@ def support_of(tag: str) -> str | None:
):
cats.append("E")

# Primary = first match in priority order; the rest are secondary.
primary = next((c for c in ("B", "C", "D", "E") if c in cats), None)
# G -- a dropped element class the audit marks support="full"/"partial".
# Either a genuine impl round-trip bug or an api.features.xml overstatement;
# both need human triage (issue #219). Without this the file falls through to
# "unknown", since B requires *every* dropped class to be support="none".
supported_missing = sorted(t for t in missing if support_of(t) in ("full", "partial"))
if supported_missing:
cats.append("G")

# Primary = first match in priority order; the rest are secondary. G is last
# so a precise enum/attribute finding still wins when one applies; otherwise
# a dropped supported element is surfaced instead of hidden in "unknown".
primary = next((c for c in ("B", "C", "D", "E", "G") if c in cats), None)
if primary is None:
warn(f"{entry.rel}: unclassified FAIL (missing={rec['missing_elements']}, "
f"mismatch={rec['mismatch_type']})")
Expand All @@ -388,6 +401,8 @@ def support_of(tag: str) -> str | None:
# Blocking features: what, if fully supported, would unblock this file.
if primary == "B":
rec["blocking_features"] = sorted(missing)
elif primary == "G":
rec["blocking_features"] = supported_missing
elif primary in ("D", "E") and div is not None and div.element:
rec["blocking_features"] = [div.element]

Expand Down Expand Up @@ -464,7 +479,7 @@ def print_summary(report: dict, out_path: Path) -> None:
total = report["summary"]["total"]
print(f"Classified {total} files from {report['dump_dir']}\n")

for cat in ("A", "B", "C", "D", "E", "F", "unknown"):
for cat in ("A", "B", "C", "D", "E", "F", "G", "unknown"):
n = counts.get(cat, 0)
if n == 0 and cat == "A":
continue
Expand All @@ -473,7 +488,7 @@ def print_summary(report: dict, out_path: Path) -> None:

ranked = _rank_blocking_features(records)
if ranked:
print("\nTop blocking features (ranked by files unblocked; B+D+E):")
print("\nTop blocking features (ranked by files unblocked; B+D+E+G):")
for feat, files, single in ranked[:15]:
print(f" {feat:<24}{files:>4} files ({single} single-blocker)")

Expand Down
29 changes: 29 additions & 0 deletions audit/tests/test_classify.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,35 @@ def test_missing_attribute(self) -> None:
self.assertEqual(rec["primary_category"], "E")
self.assertEqual(rec["mismatch_type"], "attribute-count")

def test_supported_element_drop(self) -> None:
# backup is support="full" but vanishes. That is not category B (which
# needs *every* drop to be support="none"), so it must surface as G
# rather than fall through to "unknown".
self._pair(
"wild/supdrop.xml",
_wrap("<backup>1</backup><note><pitch><step>C</step></pitch></note>"),
_wrap("<note><pitch><step>C</step></pitch></note>"),
)
rec = self._classify()["wild/supdrop.xml"]
self.assertEqual(rec["primary_category"], "G")
self.assertEqual(rec["missing_elements"], ["backup"])
self.assertEqual(rec["blocking_features"], ["backup"])
self.assertTrue(rec["is_single_blocker"])

def test_mixed_supported_and_none_drop_is_g(self) -> None:
# A supported drop (backup=full) mixed with an unsupported drop
# (credit=none) is G, not B -- and only the supported tag is a blocker.
self._pair(
"wild/mixed.xml",
_wrap("<backup>1</backup><credit>c</credit><note/>"),
_wrap("<note/>"),
)
rec = self._classify()["wild/mixed.xml"]
self.assertEqual(rec["primary_category"], "G")
self.assertEqual(rec["missing_elements"], ["backup", "credit"])
self.assertEqual(rec["blocking_features"], ["backup"])
self.assertEqual(rec["secondary_categories"], [])

def test_pipeline_error_with_status(self) -> None:
self._pair("wild/load.xml", _wrap("<note/>"), None)
self._status("wild/load.xml", "LOADFAIL")
Expand Down
8 changes: 6 additions & 2 deletions data/api.features.xml
Original file line number Diff line number Diff line change
Expand Up @@ -752,8 +752,12 @@
<feature name="part-clef" support="none">
<notes>for-part / part-clef (4.0) not modeled.</notes>
</feature>
<feature name="part-group" support="full">
<notes>api::PartGroupData; ScoreReader/ScoreWriter.</notes>
<feature name="part-group" support="partial">
<attributes>
<attribute name="type" support="yes"/>
<attribute name="number" support="yes"/>
</attributes>
<notes>api::PartGroupData via ScoreReader::startPartGroup/ScoreWriter::makePartGroupStart. Round-trips type, number, group-name, group-abbreviation, group-symbol (-&gt;bracketType), group-barline (-&gt;api::GroupBarline), and group-name-display/group-abbreviation-display as best-effort plain text (-&gt;displayName/displayAbbreviation). Partial because group-time and editorial (footnote/level) are not modeled, and formatting attributes on group-name/group-symbol/group-barline/display names (color, default-x, font-*, etc.) are dropped (value only). A part-group start with no matching stop is dropped by design: api::PartGroupData models a complete start..stop span, and an unmatched start is semantically invalid (a constraint beyond XSD).</notes>
</feature>
<feature name="part-list" support="full">
<notes>Drives ScoreData.parts ordering; ScoreReader/ScoreWriter.</notes>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/accent.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/accidental-mark.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/accidental-mark.3.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/accidental-text.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/accidental-text.3.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/accidental.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/accidental.3.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/accordion-registration.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/accordion-registration.3.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/arpeggiate.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/arpeggiate.3.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/arpeggiate.4.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/arrow-style.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/arrow.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/arrow.3.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/arrowhead.3.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/articulations.3.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/assess.4.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/bar-style.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/barline.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/barline.3.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/barre.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/bass-alter.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/bass-separator.4.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/bass-step.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/bass.4.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/beam.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/beam.3.1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/beat-repeat.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
2 changes: 1 addition & 1 deletion data/synthetic/beat-type.3.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<score-part id="id1">
<part-name>x</part-name>
</score-part>
<part-group type="start">
<part-group type="stop">
<footnote>x</footnote>
<level>x</level>
</part-group>
Expand Down
Loading
Loading