From 6321d5fcd185c1a3a20e25a212d8f0056ec4ea56 Mon Sep 17 00:00:00 2001 From: hill Date: Sun, 20 Sep 2026 23:26:01 +0200 Subject: [PATCH] Do not append to the caller's list in AbstractOctaveRepeatingScale buildNetwork completed the octave with mode.append(iComplement), so the list passed in came back longer: mode = ['M3', 'M3'] scale.OctaveRepeatingScale('c4', mode) mode # ['M3', 'M3', ] Reusing that list for a second scale then built a different scale. Build a new list instead. --- music21/scale/__init__.py | 4 ++-- music21/scale/test_scale_main.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/music21/scale/__init__.py b/music21/scale/__init__.py index ebb66478e..e3804a12f 100644 --- a/music21/scale/__init__.py +++ b/music21/scale/__init__.py @@ -6,7 +6,7 @@ # Michael Scott Asato Cuthbert # Jose Cabal-Ugaz # -# Copyright: Copyright © 2009-2011 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2026 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' @@ -1020,7 +1020,7 @@ def buildNetwork(self, mode: t.Any = None) -> None: intervalSum = interval.add(mode) iComplement = intervalSum.complement if iComplement is not None: - mode.append(iComplement) + mode = [*mode, iComplement] # a copy: mode is the caller's list self.tonicDegree = 1 self._net = intervalNetwork.IntervalNetwork(mode, diff --git a/music21/scale/test_scale_main.py b/music21/scale/test_scale_main.py index ded1bd6d9..c479a928d 100644 --- a/music21/scale/test_scale_main.py +++ b/music21/scale/test_scale_main.py @@ -5,7 +5,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2010-2024 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2010-2026 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ from __future__ import annotations @@ -233,6 +233,15 @@ def testBasic(self): ], 'notMatched': [, ]}''', pformat(sc1.match(sc2))) + def testOctaveRepeatingScaleLeavesModeAlone(self): + mode = ['M3', 'M3'] + sc = scale.OctaveRepeatingScale('c4', mode) + self.assertEqual(mode, ['M3', 'M3']) + self.assertEqual(self.pitchOut(sc.pitches), '[C4, E4, G#4, C5]') + + again = scale.OctaveRepeatingScale('c4', mode) + self.assertEqual(self.pitchOut(again.pitches), '[C4, E4, G#4, C5]') + def testCyclicalScales(self): sc = scale.CyclicalScale('c4', ['m2', 'm2'])