Skip to content

Commit

Permalink
Merge pull request #1692 from TimFelixBeyer/patch-14
Browse files Browse the repository at this point in the history
Fix #1653: Correct scale caching mechanism.
  • Loading branch information
mscuthbert authored Apr 25, 2024
2 parents 5b3b9f6 + cb0223e commit c5e3ca3
Showing 1 changed file with 21 additions and 6 deletions.
27 changes: 21 additions & 6 deletions music21/roman.py
Original file line number Diff line number Diff line change
Expand Up @@ -2488,10 +2488,10 @@ def _parseFigure(self):
if not isinstance(self._figure, str): # pragma: no cover
raise RomanNumeralException(f'got a non-string figure: {self._figure!r}')

if not self.useImpliedScale:
useScale = self._scale
else:
if self.useImpliedScale:
useScale = self.impliedScale
else:
useScale = self._scale

(workingFigure, useScale) = self._correctForSecondaryRomanNumeral(useScale)

Expand Down Expand Up @@ -3487,10 +3487,17 @@ def key(self, keyOrScale):
# store for later
_keyCache[keyOrScale.tonicPitchNameWithCase] = keyOrScale
elif 'Scale' in keyClasses:
if keyOrScale.name in _scaleCache:
keyOrScale = _scaleCache[keyOrScale.name]
# Need unique 'hash' for each scale. Names is not enough as there are
# multiple scales with the same name but different pitches.
scaleHash = keyOrScale.name
if getattr(keyOrScale, 'isConcrete', False):
scaleHash += '_'.join(
[p.nameWithOctave for p in keyOrScale.pitches]
)
if scaleHash in _scaleCache:
keyOrScale = _scaleCache[scaleHash]
else:
_scaleCache[keyOrScale.name] = keyOrScale
_scaleCache[scaleHash] = keyOrScale
else:
raise RomanNumeralException(
f'Cannot get a key from this object {keyOrScale!r}, send only '
Expand Down Expand Up @@ -4553,6 +4560,14 @@ def test_int_figure_case_matters(self):
rn = RomanNumeral(4, 'C')
self.assertEqual(rn.figure, 'IV')

def test_scale_caching(self):
mcs = scale.ConcreteScale('c', pitches=('C', 'D', 'E', 'F', 'G', 'A', 'B'))
rn = mcs.romanNumeral('IV7')
self.assertEqual([p.unicodeName for p in rn.pitches], ['F', 'A', 'C', 'E'])
mcs = scale.ConcreteScale('c', pitches=('C', 'D', 'E-', 'F', 'G', 'A', 'B'))
rn = mcs.romanNumeral('IV7')
self.assertEqual([p.unicodeName for p in rn.pitches], ['F', 'A', 'C', 'E♭'])


class TestExternal(unittest.TestCase):
show = True
Expand Down

0 comments on commit c5e3ca3

Please sign in to comment.