Skip to content

Add typing to RomanText#1937

Merged
mscuthbert merged 11 commits into
masterfrom
typing_misc
Jun 24, 2026
Merged

Add typing to RomanText#1937
mscuthbert merged 11 commits into
masterfrom
typing_misc

Conversation

@mscuthbert

@mscuthbert mscuthbert commented Jun 19, 2026

Copy link
Copy Markdown
Member

Originally this PR was going to add type annotations across a lot of directories, but they've been split out:

So, only remaining is romanText/ (clercqTemperley, rtObjects, translate, tsvConverter, writeRoman)

Two latent bugs surfaced while typing and fixed:

  • CTSong.init stored the keyword names ('title'/'year') rather than their values
  • search/segment.py saveScoreDict opened the file 'wb' (binary) while json.dump writes text

AI-assisted (Claude)

@coveralls

coveralls commented Jun 19, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 93.132% (+0.008%) from 93.124% — typing_misc into master

mscuthbert added a commit that referenced this pull request Jun 21, 2026
These two folders are now typed in branch typing_small_folders (its own
PR) to keep #1937 reviewable. Reverting them here to master's state so
there is no overlap between the two PRs.

AI-assisted (Claude)
alexandermorgan pushed a commit to alexandermorgan/music21 that referenced this pull request Jun 21, 2026
Split out of cuthbertLab#1937 to keep that PR reviewable. Adds parameter/return type
annotations to:
- ipython21/ (__init__, ipExtension, converters)
- languageExcerpts/ (instrumentLookup, naturalLanguageObjects)

Whole-package mypy + ruff clean; doctests pass.

AI-assisted (Claude)
@mscuthbert mscuthbert changed the title Add more Typing to romanText, scale, search, figuredBass etc Add more Typing to romanText, scale, and search Jun 21, 2026
@mscuthbert mscuthbert marked this pull request as draft June 22, 2026 08:22
Type-annotate the romanText package (clercqTemperley, rtObjects, translate,
tsvConverter, writeRoman). Also:

- Fix a CTSong keyword bug where `year=` was assigning the keyword *name*
  rather than its value; add a CTSong title/year test.
- Annotate features.Feature.__init__ / _getVectors (missed by the small-folders
  typing pass).
- Note in AGENTS.md that PR CI tests the branch merged with the latest master,
  so merge master before opening/updating a PR.

AI-assisted (Claude)
Bare `assert` in a test gives a poor traceback on failure. Replace them with
real unittest assertions:

- testReA: precede each Optional-narrowing `assert g is not None` with
  `self.assertIsNotNone(g)` (the meaningful check); the bare assert stays after
  it -- guaranteed to succeed -- purely so mypy narrows the re.Match | None.
- testRepeats: `assert s.duration.quarterLength == 10` -> assertEqual.
- writeRoman test: `assert ....endswith(...)` -> assertTrue.

AI-assisted (Claude)
Collapse the redundant `self.assertIsNotNone(g)` + `assert g is not None`
pairs into a single `assert g is not None, '<regex> did not match'`, which
narrows re.Match | None for mypy and gives a useful failure message.

AI-assisted (Claude)
@mscuthbert mscuthbert changed the title Add more Typing to romanText, scale, and search Add typing to RomanText Jun 24, 2026
@mscuthbert mscuthbert marked this pull request as ready for review June 24, 2026 01:59
…sentinels' None

These |None types were never really None -- the call sites already cast them
away. Tighten them and remove the casts:

- _copySingleMeasure / _copyMultipleMeasures now require kCurrent: key.Key (a
  Key is always supplied, defaulting to C at instantiation) and return a
  non-Optional Key. The dead "no past key definitions" guards are removed.
- Both now raise RomanTextTranslateException if the copy *source* measure(s)
  are not found, instead of returning None / an empty list and failing obscurely
  downstream. Added tests for both (forward-reference copy targets).
- currentMeasureToken and lastMeasureToken are initialised to a measure-0
  RTMeasure sentinel (always overwritten before use), so they are typed as a
  plain RTMeasure and the four t.casts are gone.

previousChordInMeasure stays Optional on purpose: it is reset to None at the
start of every measure and the `is None` checks are the first-chord-in-measure
detection.

AI-assisted (Claude)
…asures

translateSingleMeasure cast self.previousRn to GeneralNote when adjusting the
last chord's duration, but previousRn is None until the first chord atom is
seen. A piece that begins with an empty or key-only measure therefore crashed
with "AttributeError: 'NoneType' object has no attribute 'quarterLength'" (the
cast was masking it). Guard on `self.previousRn is not None` instead -- if no
chord was added there is no last chord to resize -- which also removes the cast.
Added a regression test.

AI-assisted (Claude)
…test

Assert the empty first measure has no RomanNumeral and the second measure
parses as a I chord, so the test guards correct parsing of a piece that begins
without chord atoms, not merely that it does not crash.

AI-assisted (Claude)
…None

previousRn was typed note.GeneralNote|None but only ever holds a RomanNumeral
(a chord) or a Rest (from an N.C. atom), or None before the first chord.
Narrow the annotation accordingly. No behavior change -- it still starts as
None, so the existing is-None guards are unaffected.

AI-assisted (Claude)
…gap bug)

Note next to the initial previousRn assignment that it should start as a
note.Rest (dropping None) so a piece beginning before its first chord -- e.g.
one starting with N.C. -- gets leading rests rather than a gap.

AI-assisted (Claude)
Cross-reference the previousRn TODO from the measure-start back-fill: it does
not fire at the start of a piece because previousRn is None there.

AI-assisted (Claude)
key, stream, rtObjects, and roman are already imported at module level; the
new tests re-imported them, tripping pylint's redefined-outer-name / reimported
warnings. Use the module-level names (keep only the local converter import,
which is not module-level).

AI-assisted (Claude)
@mscuthbert mscuthbert merged commit 603fa24 into master Jun 24, 2026
7 checks passed
@mscuthbert mscuthbert deleted the typing_misc branch June 24, 2026 03:16
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