Skip to content

fix: use full chord type for roman-numeral sevenths in Add harmony dialog#552

Merged
azfoo merged 3 commits into
TimeLineAnnotator:devfrom
FelipeDefensor:fix/harmony-roman-seventh-quality
Jul 21, 2026
Merged

fix: use full chord type for roman-numeral sevenths in Add harmony dialog#552
azfoo merged 3 commits into
TimeLineAnnotator:devfrom
FelipeDefensor:fix/harmony-roman-seventh-quality

Conversation

@FelipeDefensor

@FelipeDefensor FelipeDefensor commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Warning

AI-generated — needs verifying. This investigation, fix, and tests were produced by an AI agent (Claude Code) and have not been independently verified by a human. Please review carefully before merging — see the checklist at the bottom.

Summary

Typing a roman-numeral seventh chord (e.g. V7) in the Add harmony dialog selected the triad quality (Major) instead of the seventh quality (Dominant seventh). Reported against v0.6.3.

Root cause

The roman-numeral parse path in _get_params_from_music21_object (tilia/timelines/harmony/components/harmony.py) read music21's RomanNumeral.impliedQuality, which only reflects the triad quality (major/minor/diminished/augmented) and ignores the seventh/extension. So V7 resolved to major, and the dialog's quality combobox selected "Major".

This is a regression from commit 7a76fdc ("chore: more accurate naming"), a chord_* → letter_* rename. It correctly renamed the set side (roman_numeral.chord_typeroman_numeral.letter_type), but on the read side changed obj.chord_type to obj.impliedQuality instead of obj.letter_type. That left letter_type set-but-never-read, and the reader silently picked up music21's triad-only attribute.

letter_type is computed from the chord's actual pitches (Chord(roman.pitches).commonNameCHORD_COMMON_NAME_TO_TYPE), so it carries the correct full chord type.

Fix

One line:

-        quality = obj.impliedQuality
+        quality = obj.letter_type

Tests

Adds TestRomanNumeralParsing to tests/ui/dialogs/test_select_harmony_params.py. It drives the dialog the way a user types (char-by-char into the line edit via the existing parse_text helper) and asserts on the resulting combobox selection — i.e. it exercises the exact reported symptom, not just the parse function.

Cases: V (triad, unchanged), V7, V65, V43, V42, ii7, viio7, and the applied chord V7/V. Confirmed these fail on the buggy code (assert 'major' == 'dominant-seventh') and pass with the fix. Full harmony suite (171 tests) green; ruff clean.

Reviewer checklist (AI output — please verify)

  • Music-theory correctness of the expected qualities/inversions for the parametrized roman numerals.
  • letter_type is always set whenever the parse path returns kind == "roman" (it is assigned inside the try block in _get_music21_object_from_text). removed monkey-patched letter-type
  • No other reader relies on the previous impliedQuality behavior for roman numerals.

@FelipeDefensor FelipeDefensor added this to the 0.6.4 milestone Jun 25, 2026
@FelipeDefensor
FelipeDefensor requested a review from azfoo June 25, 2026 13:17
FelipeDefensor and others added 3 commits July 20, 2026 17:53
Typing a roman-numeral seventh (e.g. "V7") in the Add harmony dialog
selected the triad quality ("Major") instead of the seventh quality
("Dominant seventh").

The roman-numeral parse path read music21's RomanNumeral.impliedQuality,
which only reflects the triad. Commit 7a76fdc ("more accurate naming")
renamed the attribute holding the full chord type from chord_type to
letter_type, but changed the reader to impliedQuality instead of
letter_type, leaving letter_type set-but-unread. Read letter_type so the
full chord type (derived from the chord's pitches) is used.

Adds regression tests covering V/V7/V65/V43/V42, ii7, viio7, and V7/V.
letter_type does not actually exist on m21's RomanNumeral. RomanNumeral is also  a subclass of Chord, so this removes the extra conversion.
@azfoo
azfoo force-pushed the fix/harmony-roman-seventh-quality branch from c3fb3d8 to 9dcf3bf Compare July 21, 2026 09:43
@azfoo
azfoo merged commit b7346ea into TimeLineAnnotator:dev Jul 21, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants