Repository: cuthbertLab/music21
Pull request #1093 (2021-08-20 19:52:13)

Reiterate accidentals each measure in Stream.makeAccidentals()
Fixes issue demonstrated in regression test. Need to reiterate accidentals in subsequent measures when making accidentals on a score.

Surely escaped notice in the past by musicxml export pipeline running makeNotation() and ultimately `Part.makeAccidentals()` rather than `Stream.makeAccidentals()`.


Patch:
diff --git a/music21/braille/basic.py b/music21/braille/basic.py
index 9674c8993..c83777046 100644
--- a/music21/braille/basic.py
+++ b/music21/braille/basic.py
@@ -1423,7 +1423,7 @@ def brailleUnicodeToBrailleAscii(brailleUnicode):
     .. note:: The function works by corresponding braille symbols to ASCII symbols.
         The table which corresponds to said values can be found
         `here <https://en.wikipedia.org/wiki/Braille_ASCII#Braille_ASCII_values>`_.
-        Because of the way in which the braille symbols translate2, the resulting
+        Because of the way in which the braille symbols translate, the resulting
         ASCII string will look to a non-reader as gibberish. Also, the eighth-note notes
         in braille
         music are one-off their corresponding letters in both ASCII and written braille.
diff --git a/music21/converter/subConverters.py b/music21/converter/subConverters.py
index 966134cdd..4e73c5316 100644
--- a/music21/converter/subConverters.py
+++ b/music21/converter/subConverters.py
@@ -501,7 +501,7 @@ class ConverterBraille(SubConverter):
 
     def write(self, obj, fmt, fp=None, subformats=None, **keywords):  # pragma: no cover
         from music21 import braille
-        dataStr = braille.translate.objectToBraille(obj, **keywords)
+        dataStr = braille.translate.objectToBraille(obj)
         if subformats is not None and 'ascii' in subformats:
             dataStr = braille.basic.brailleUnicodeToBrailleAscii(dataStr)
         fp = self.writeDataStream(fp, dataStr)
@@ -1547,15 +1547,6 @@ class Test(unittest.TestCase):
         for out in (out1, out2):
             os.remove(out)
 
-    def testBrailleKeywords(self):
-        from music21 import converter
-
-        p = converter.parse('tinyNotation: c1 d1 e1 f1')
-        out = p.write('braille', debug=True)
-        with open(out, 'r') as f:
-            self.assertIn('<music21.braille.segment BrailleSegment>', f.read())
-        os.remove(out)
-
 
 class TestExternal(unittest.TestCase):
     show = True
diff --git a/music21/pitch.py b/music21/pitch.py
index ea3211495..f186c7836 100644
--- a/music21/pitch.py
+++ b/music21/pitch.py
@@ -3065,7 +3065,7 @@ class Pitch(prebase.ProtoM21Object):
             if tempStep in ('C', 'D', 'F', 'G', 'H'):
                 firstFlatName = 'es'
             else:  # A, E.  Bs should never occur...
-                firstFlatName = u's'
+                firstFlatName = 's'
             multipleFlats = abs(tempAlter) - 1
             tempName = tempStep + firstFlatName + (multipleFlats * 'es')
             return tempName
diff --git a/music21/stream/base.py b/music21/stream/base.py
index 6eefbfc53..08335a418 100644
--- a/music21/stream/base.py
+++ b/music21/stream/base.py
@@ -6655,7 +6655,16 @@ class Stream(core.StreamCoreMixin, base.Music21Object):
         if tiePitchSet is None:
             tiePitchSet = set()
 
+        last_measure: Optional[Measure] = None
+
         for e in noteIterator:
+            if e.activeSite is not None and e.activeSite.isMeasure:
+                if last_measure is not None and e.activeSite is not last_measure:
+                    # New measure encountered: move pitchPast to
+                    # pitchPastMeasure and clear pitchPast
+                    pitchPastMeasure = pitchPast[:]
+                    pitchPast = []
+                last_measure = e.activeSite
             if isinstance(e, note.Note):
                 if e.pitch.nameWithOctave in tiePitchSet:
                     lastNoteWasTied = True


Test patch:
diff --git a/music21/stream/tests.py b/music21/stream/tests.py
index 0f024daa7..e57c98dfb 100644
--- a/music21/stream/tests.py
+++ b/music21/stream/tests.py
@@ -2720,6 +2720,20 @@ class Test(unittest.TestCase):
         m = p1.measure(1)
         self.assertEqual(str(m.rightBarline), '<music21.bar.Barline type=final>')
 
+    def testMakeAccidentalsInScore(self):
+        '''
+        Making accidentals on a score having a part with measures
+        should still reiterate accidentals measure by measure.
+        '''
+        n1 = note.Note('f#', type='whole')
+        n2 = note.Note('f#', type='whole')
+        m1 = Measure(n1)
+        m2 = Measure(n2)
+        p = Part([m1, m2])
+        s = Score(p)
+        s.makeAccidentals(inPlace=True)
+        self.assertIs(s[note.Note].last().pitch.accidental.displayStatus, True)
+
     def testMakeAccidentalsWithKeysInMeasures(self):
         scale1 = ['c4', 'd4', 'e4', 'f4', 'g4', 'a4', 'b4', 'c5']
         scale2 = ['c', 'd', 'e-', 'f', 'g', 'a-', 'b-', 'c5']