Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion music21/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
'''
from __future__ import annotations

__version__ = '11.0.0b7'
__version__ = '11.0.0b8'

def get_version_tuple(vv):
v = vv.split('.')
Expand Down
2 changes: 1 addition & 1 deletion music21/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<class 'music21.base.Music21Object'>

>>> music21.VERSION_STR
'11.0.0b7'
'11.0.0b8'

Alternatively, after doing a complete import, these classes are available
under the module "base":
Expand Down
21 changes: 11 additions & 10 deletions music21/pitch.py
Original file line number Diff line number Diff line change
Expand Up @@ -5048,6 +5048,17 @@ def set_displayStatus(newDisplayStatus: bool) -> None:
set_displayStatus(True)
return

# here tied and always are treated the same; we assume that
# making ties sets the displayStatus, and thus we would not be
# overriding that display status here
if (cautionaryAll is True
or (acc is not None
and acc.displayType in ('even-tied', 'always'))):
# show all accidentals, no matter what is in the past
# or in the key signature
set_displayStatus(True)
return # do not search past

# no pitches in the past list
if not pitchPastAll:
# if we have no past, we show the accidental if this pitch name
Expand Down Expand Up @@ -5089,16 +5100,6 @@ def set_displayStatus(newDisplayStatus: bool) -> None:
break
# nope, no conflicting accidentals at this name and octave in the past

# here tied and always are treated the same; we assume that
# making ties sets the displayStatus, and thus we would not be
# overriding that display status here
if (cautionaryAll is True
or (acc is not None
and acc.displayType in ('even-tied', 'always'))):
# show all accidentals, even if past encountered
set_displayStatus(True)
return # do not search past

# store if a match was found and display set from past pitches
setFromPitchPast = False

Expand Down
49 changes: 49 additions & 0 deletions music21/test/test_pitch.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,55 @@ def testOverrideDisplayStatus(self):
n.pitch.updateAccidentalDisplay(overrideStatus=True, alteredPitches=k.alteredPitches)
self.assertIs(n.pitch.accidental.displayStatus, False)

def testDisplayTypeAlwaysWithNothingInPast(self):
'''
`displayType='always'` and `cautionaryAll` win over the key signature
even for the first pitch of a part, where nothing precedes it.

AI-assisted (Claude).
'''
p = Pitch('An2')
p.accidental.displayType = 'always'
p.updateAccidentalDisplay()
self.assertIs(p.accidental.displayStatus, True)

# a sharp already implied by the key signature still shows
p = Pitch('F#4')
p.accidental.displayType = 'always'
p.updateAccidentalDisplay(alteredPitches=key.Key('G').alteredPitches)
self.assertIs(p.accidental.displayStatus, True)

# cautionaryAll creates the natural that was not there
p = Pitch('B4')
p.updateAccidentalDisplay(cautionaryAll=True)
self.assertEqual(p.accidental.name, 'natural')
self.assertIs(p.accidental.displayStatus, True)

# 'even-tied' behaves the same as 'always' here
p = Pitch('E-3')
p.accidental.displayType = 'even-tied'
p.updateAccidentalDisplay(alteredPitches=key.Key('E-').alteredPitches)
self.assertIs(p.accidental.displayStatus, True)

# in a stream, every note of the part shows, not just the ones after the first
s = converter.parse('tinyNotation: AAn2 Fn')
for n in s.recurse().notes:
n.pitch.accidental.displayType = 'always'
s.makeAccidentals(inPlace=True)
self.assertEqual([n.pitch.accidental.displayStatus for n in s.recurse().notes],
[True, True])

# regression guard: a normal displayType is untouched by the above
p = Pitch('F#4')
p.updateAccidentalDisplay(alteredPitches=key.Key('G').alteredPitches)
self.assertIs(p.accidental.displayStatus, False)

# regression guard: with a non-empty past, repeated pitches are unchanged
past = [Pitch('c#4')]
p = Pitch('c#4')
p.updateAccidentalDisplay(pitchPast=past)
self.assertIs(p.accidental.displayStatus, False)

def testImplicitToExplicitNatural(self):
p = converter.parse('tinyNotation: 2/4 f4 fn4')
last_note = p.recurse().notes.last()
Expand Down
Loading