Skip to content

Commit

Permalink
Merge pull request #1734 from cuthbertLab/tn-trip-ties
Browse files Browse the repository at this point in the history
Some Note/TinyNotation typing
  • Loading branch information
mscuthbert authored Sep 18, 2024
2 parents cfabad1 + 123cb0d commit e05fc53
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 84 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Maintainers will respect confidentiality with regard to reports.

## Acknowledgements ##

The early development of `music21` was been supported by
The early development of `music21` was supported by
the generosity of the Seaver Institute and the
National Endowment for the Humanities, along with MIT's Music and Theater Arts Section
and the School of Humanities, Arts, and Social Sciences.
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@
],
"source": [
"for n in alto.recurse().notes:\n",
" n.stemDirection = None\n",
" n.stemDirection = 'unspecified'\n",
"\n",
"alto.show()"
]
Expand Down
1 change: 0 additions & 1 deletion music21/meter/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ class TimeSignatureBase(base.Music21Object):
pass

class TimeSignature(TimeSignatureBase):
# noinspection GrazieInspection
r'''
The `TimeSignature` object represents time signatures in musical scores
(4/4, 3/8, 2/4+5/16, Cut, etc.).
Expand Down
2 changes: 0 additions & 2 deletions music21/meter/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,6 @@ def slashCompoundToFraction(value: str) -> NumDenomTuple:
return tuple(post)


# Pycharm is having trouble with the unmatched parentheses in the docs
# noinspection GrazieInspection
@lru_cache(512)
def slashMixedToFraction(valueSrc: str) -> tuple[NumDenomTuple, bool]:
'''
Expand Down
135 changes: 66 additions & 69 deletions music21/note.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,32 +680,9 @@ def tie(self) -> tie.Tie|None:
def tie(self, value: tie.Tie|None):
self._tie = value

def _getLyric(self) -> str|None:
if not self.lyrics:
return None

allText = [ly.text for ly in self.lyrics]
return '\n'.join([textStr for textStr in allText if textStr is not None])

def _setLyric(self, value: str|Lyric|None) -> None:
self.lyrics = []
if value is None:
return

if isinstance(value, Lyric):
self.lyrics.append(value)
return

if not isinstance(value, str):
value = str(value)

values = value.split('\n')
for i, v in enumerate(values):
self.lyrics.append(Lyric(v, number=i + 1))

lyric = property(_getLyric,
_setLyric,
doc=r'''
@property
def lyric(self) -> str|None:
r'''
The lyric property can
be used to get and set a lyric for this
Note, Chord, or Rest. This is a simplified version of the more general
Expand Down Expand Up @@ -749,7 +726,30 @@ def _setLyric(self, value: str|Lyric|None) -> None:
* Changed in v6.7: added setting to a Lyric object. Removed undocumented
setting to False instead of setting to None
''')
'''
if not self.lyrics:
return None

allText = [ly.text for ly in self.lyrics]
return '\n'.join([textStr for textStr in allText if textStr is not None])

@lyric.setter
def lyric(self, value: str|Lyric|None) -> None:
self.lyrics = []
if value is None:
return

if isinstance(value, Lyric):
self.lyrics.append(value)
return

if not isinstance(value, str):
value = str(value)

values = value.split('\n')
for i, v in enumerate(values):
self.lyrics.append(Lyric(v, number=i + 1))


def addLyric(self,
text,
Expand Down Expand Up @@ -1076,21 +1076,10 @@ def __deepcopy__(self, memo=None):
# environLocal.printDebug(['calling NotRest.__deepcopy__', self])
return self._deepcopySubclassable(memo=memo)

def _getStemDirection(self) -> str:
return self._stemDirection

def _setStemDirection(self, direction):
if direction is None:
direction = 'unspecified' # allow setting to None meaning
elif direction == 'none':
direction = 'noStem' # allow setting to none or None
elif direction not in stemDirectionNames:
raise NotRestException(f'not a valid stem direction name: {direction}')
self._stemDirection = direction

stemDirection = property(_getStemDirection,
_setStemDirection,
doc='''
@property
def stemDirection(self) -> str:
r'''
Get or set the stem direction of this NotRest object.
Valid stem direction names are found in note.stemDirectionNames (see below).
Expand Down Expand Up @@ -1124,7 +1113,18 @@ def _setStemDirection(self, direction):
>>> n.stemDirection = None
>>> n.stemDirection
'unspecified'
''')
'''
return self._stemDirection

@stemDirection.setter
def stemDirection(self, direction: None|str):
if direction is None:
direction = 'unspecified' # allow setting to None meaning
elif direction == 'none':
direction = 'noStem' # allow setting to none or None
elif direction not in stemDirectionNames:
raise NotRestException(f'not a valid stem direction name: {direction}')
self._stemDirection = direction

@property
def notehead(self) -> str:
Expand Down Expand Up @@ -1617,32 +1617,30 @@ def __deepcopy__(self: Note, memo=None) -> Note:
# --------------------------------------------------------------------------
# property access

def _getName(self) -> str:
@property
def name(self) -> str:
'''
Return or set the pitch name from the :class:`~music21.pitch.Pitch` object.
See `Pitch`'s attribute :attr:`~music21.pitch.Pitch.name`.
'''
return self.pitch.name

def _setName(self, value: str):
@name.setter
def name(self, value: str):
self.pitch.name = value

name = property(_getName,
_setName,
doc='''
Return or set the pitch name from the :class:`~music21.pitch.Pitch` object.
See `Pitch`'s attribute :attr:`~music21.pitch.Pitch.name`.
''')

def _getNameWithOctave(self) -> str:
@property
def nameWithOctave(self) -> str:
'''
Return or set the pitch name with octave from the :class:`~music21.pitch.Pitch` object.
See `Pitch`'s attribute :attr:`~music21.pitch.Pitch.nameWithOctave`.
'''
return self.pitch.nameWithOctave

def _setNameWithOctave(self, value: str):
@nameWithOctave.setter
def nameWithOctave(self, value: str):
self.pitch.nameWithOctave = value

nameWithOctave = property(_getNameWithOctave,
_setNameWithOctave,
doc='''
Return or set the pitch name with octave from the :class:`~music21.pitch.Pitch` object.
See `Pitch`'s attribute :attr:`~music21.pitch.Pitch.nameWithOctave`.
''')

@property
def step(self) -> StepName:
'''
Expand All @@ -1655,19 +1653,18 @@ def step(self) -> StepName:
def step(self, value: StepName):
self.pitch.step = value

def _getOctave(self) -> int|None:
@property
def octave(self) -> int|None:
'''
Return or set the octave value from the :class:`~music21.pitch.Pitch` object.
See :attr:`~music21.pitch.Pitch.octave`.
'''
return self.pitch.octave

def _setOctave(self, value: int|None):
@octave.setter
def octave(self, value: int|None):
self.pitch.octave = value

octave = property(_getOctave,
_setOctave,
doc='''
Return or set the octave value from the :class:`~music21.pitch.Pitch` object.
See :attr:`~music21.pitch.Pitch.octave`.
''')

@property
def pitches(self) -> tuple[Pitch, ...]:
'''
Expand Down
26 changes: 17 additions & 9 deletions music21/tinyNotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,10 @@ class State:
# expires after N tokens or never.
autoExpires: typing.Literal[False]|int = False

def __init__(self, parent=None, stateInfo=None):
self.affectedTokens = []
self.parent = parent
self.stateInfo = stateInfo
def __init__(self, parent: Converter|None = None, stateInfo: str|None = None):
self.affectedTokens: list[Music21Object] = []
self.parent: Converter|None = parent
self.stateInfo: str|None = stateInfo
# print('Adding state', self, parent.activeStates)

def start(self):
Expand All @@ -293,19 +293,25 @@ def end(self) -> Music21Object|None:
'''
return None

def affectTokenBeforeParse(self, tokenStr):
def affectTokenBeforeParse(self, tokenStr: str) -> str:
'''
called to modify the string of a token.
'''
return tokenStr

def affectTokenAfterParseBeforeModifiers(self, m21Obj):
def affectTokenAfterParseBeforeModifiers(
self,
m21Obj: Music21Object
) -> Music21Object:
'''
called after the object has been acquired but before modifiers have been applied.
'''
return m21Obj

def affectTokenAfterParse(self, m21Obj):
def affectTokenAfterParse(
self,
m21Obj: Music21Object
) -> Music21Object:
'''
called to modify the tokenObj after parsing
Expand All @@ -318,6 +324,8 @@ def affectTokenAfterParse(self, m21Obj):
self.end()
# this is a hack that should be done away with...
p = self.parent
if p is None:
return m21Obj

# I thought this was potentially O(n^2) but it's actually
# just O(n) on activeStates and on pop() operation.
Expand Down Expand Up @@ -545,7 +553,7 @@ class RestToken(NoteOrRestToken):
'''
A token starting with 'r', representing a rest.
'''
def parse(self, parent=None):
def parse(self, parent: Converter|None = None):
r = note.Rest()
self.applyDuration(r, self.token, parent)
return r
Expand Down Expand Up @@ -586,7 +594,7 @@ def __init__(self, token=''):
super().__init__(token)
self.isEditorial = False

def parse(self, parent=None):
def parse(self, parent: Converter|None = None):
'''
Extract the pitch from the note and then returns the Note.
'''
Expand Down
2 changes: 1 addition & 1 deletion music21/tree/verticality.py
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ def newNote(ts: spans.PitchedTimespan, n: note.Note) -> note.Note:
nNew.pitch = n.pitch

if nNew.stemDirection != 'noStem':
nNew.stemDirection = None
nNew.stemDirection = 'unspecified'
if not addTies:
return nNew

Expand Down

0 comments on commit e05fc53

Please sign in to comment.