Skip to content

Fix roman.RomanNumeral Key cache colliding across modes#1906

Merged
mscuthbert merged 2 commits into
masterfrom
fix-roman-key-cache-mode
Jun 2, 2026
Merged

Fix roman.RomanNumeral Key cache colliding across modes#1906
mscuthbert merged 2 commits into
masterfrom
fix-roman-key-cache-mode

Conversation

@mscuthbert
Copy link
Copy Markdown
Member

@mscuthbert mscuthbert commented Jun 2, 2026

Creating a RomanNumeral in a non-major/minor mode (like Lydian or Dorian) poisons the cache for the major key (Lydian) or minor (Dorian, Phyrgian, etc.) on the same tonic.

After creating RomanNumeral('I', key.Key('C', 'lydian')), a subsequent RomanNumeral('I', 'C') returns a C lydian key instead of C major.

Cause

roman.py's _keyCache was keyed by Key.tonicPitchNameWithCase, which only distinguishes major (upper case) from minor (lower case). Every other mode falls back to the upper-case tonic, so C lydian was stored under 'C' and collided with C major.

Fix

Add a _keyCacheKey() helper used at both cache-store sites:

  • major/minor keep the case-only form ('C', 'c') so existing fast string lookups still hit.
  • any other mode is qualified with its mode name ('C lydian') so it can never be returned for a C major request.

AI-assisted (Claude)

The _keyCache in roman.py was keyed by Key.tonicPitchNameWithCase, which
only encodes major (upper case) vs minor (lower case). Any other mode
(lydian, dorian, etc.) falls back to the upper-case tonic, so a C lydian
Key was cached under 'C' and collided with C major: after creating a
RomanNumeral in C lydian, a later RomanNumeral('I', 'C') returned the
cached lydian Key instead of C major.

Add a _keyCacheKey() helper used at both cache-store sites: major/minor
keep the case-only form so fast string lookups still hit, and any other
mode is qualified with its mode name (e.g. 'C lydian') so it cannot be
returned for a C major request. Add deterministic regression tests that
clear the cache and check both orderings and the resulting cache keys.

AI-assisted (Claude)
@mscuthbert mscuthbert marked this pull request as ready for review June 2, 2026 05:55
@coveralls
Copy link
Copy Markdown

coveralls commented Jun 2, 2026

Coverage Status

coverage: 93.049% (+0.003%) from 93.046% — fix-roman-key-cache-mode into master

@mscuthbert mscuthbert merged commit 82553b6 into master Jun 2, 2026
8 checks passed
@mscuthbert mscuthbert deleted the fix-roman-key-cache-mode branch June 2, 2026 06:25
@mscuthbert
Copy link
Copy Markdown
Member Author

Bug since at least 2015. Maybe older

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