Skip to content

Commit

Permalink
Merge pull request #1745 from cuthbertLab/2025-jan-misc
Browse files Browse the repository at this point in the history
Astroid 1015 + misc improvements jan
  • Loading branch information
mscuthbert authored Jan 23, 2025
2 parents 851e674 + 1097e77 commit 62b0bf4
Show file tree
Hide file tree
Showing 17 changed files with 153 additions and 156 deletions.
14 changes: 6 additions & 8 deletions music21/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ def getOffsetBySite(
*,
returnSpecial: t.Literal[False] = False,
) -> OffsetQL:
return 0.0 # dummy until Astroid #1015 is fixed. Replace with ...
...

@overload
def getOffsetBySite(
Expand All @@ -939,8 +939,7 @@ def getOffsetBySite(
*,
returnSpecial: bool = False,
) -> OffsetQL|OffsetSpecial:
return 0.0 # dummy until Astroid #1015 is fixed. Replace with ...
# using bool instead of t.Literal[True] because of other errors
...

def getOffsetBySite(
self,
Expand Down Expand Up @@ -1332,7 +1331,7 @@ def getContextByClass(
followDerivation=True,
priorityTargetOnly=False,
) -> _M21T|None:
return None # until Astroid #1015
...

@overload
def getContextByClass(
Expand All @@ -1344,7 +1343,7 @@ def getContextByClass(
followDerivation=True,
priorityTargetOnly=False,
) -> Music21Object|None:
return None # until Astroid #1015
...

def getContextByClass(
self,
Expand Down Expand Up @@ -1830,7 +1829,7 @@ def contextSites(
followDerivation=True,
priorityTargetOnly=False,
) -> Generator[ContextSortTuple, None, None]:
pass
...

@overload
def contextSites(
Expand All @@ -1845,8 +1844,7 @@ def contextSites(
followDerivation=True,
priorityTargetOnly=False,
) -> Generator[ContextTuple, None, None]:
pass

...

def contextSites(
self,
Expand Down
67 changes: 34 additions & 33 deletions music21/chord/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,7 @@ def annotateIntervals(
sortPitches: bool = True,
returnList: t.Literal[True]
) -> list[str]:
pass
...

@overload
def annotateIntervals(
Expand All @@ -1124,7 +1124,7 @@ def annotateIntervals(
sortPitches: bool = True,
returnList: t.Literal[False] = False
) -> None:
pass
...

@overload
def annotateIntervals(
Expand All @@ -1135,7 +1135,7 @@ def annotateIntervals(
sortPitches: bool = True,
returnList: t.Literal[False] = False
) -> _ChordType:
pass
...

def annotateIntervals(
self: _ChordType,
Expand Down Expand Up @@ -1271,29 +1271,32 @@ def areZRelations(self: _ChordType, other: _ChordType) -> bool:
return False

@overload
def bass(self,
newbass: None = None,
*,
find: bool|None = None,
allow_add: bool = False,
) -> pitch.Pitch:
return self.pitches[0] # dummy until Astroid 1015 is fixed.
def bass(
self,
newbass: None = None,
*,
find: bool|None = None,
allow_add: bool = False,
) -> pitch.Pitch:
...

@overload
def bass(self,
newbass: str|pitch.Pitch|note.Note,
*,
find: bool|None = None,
allow_add: bool = False,
) -> None:
return None
def bass(
self,
newbass: str|pitch.Pitch|note.Note,
*,
find: bool|None = None,
allow_add: bool = False,
) -> None:
...

def bass(self,
newbass: None|str|pitch.Pitch|note.Note = None,
*,
find: bool|None = None,
allow_add: bool = False,
) -> pitch.Pitch|None:
def bass(
self,
newbass: None|str|pitch.Pitch|note.Note = None,
*,
find: bool|None = None,
allow_add: bool = False,
) -> pitch.Pitch|None:
'''
Generally used to find and return the bass Pitch:
Expand Down Expand Up @@ -1481,12 +1484,11 @@ def canBeTonic(self) -> bool:
def closedPosition(
self: _ChordType,
*,
forceOctave: int|None,
forceOctave: int|None = None,
inPlace: t.Literal[True],
leaveRedundantPitches=False
leaveRedundantPitches: bool = False
) -> None:
# astroid 1003
return None
...

@overload
def closedPosition(
Expand All @@ -1496,8 +1498,7 @@ def closedPosition(
inPlace: t.Literal[False] = False,
leaveRedundantPitches: bool = False
) -> _ChordType:
# astroid 1003
return self
...

def closedPosition(
self: _ChordType,
Expand Down Expand Up @@ -2298,7 +2299,7 @@ def inversion(
testRoot: pitch.Pitch|None = None,
transposeOnSet: bool = True
) -> None:
return None # dummy until Astroid 1015 is fixed
...

@overload
def inversion(
Expand All @@ -2309,7 +2310,7 @@ def inversion(
testRoot: pitch.Pitch|None = None,
transposeOnSet: bool = True
) -> int:
return -1 # dummy until Astroid 1015 is fixed
...

def inversion(
self,
Expand Down Expand Up @@ -3799,15 +3800,15 @@ def root(self,
*,
find: bool|None = None
) -> pitch.Pitch:
return self.pitches[0] # dummy until Astroid 1015 is fixed.
...

@overload
def root(self,
newroot: str|pitch.Pitch|note.Note,
*,
find: bool|None = None
) -> None:
return None # dummy until Astroid 1015 is fixed.
...

def root(self,
newroot: None|str|pitch.Pitch|note.Note = None,
Expand Down
20 changes: 16 additions & 4 deletions music21/common/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,17 @@ def __repr__(self):

class StrEnum(str, Enum, metaclass=StrEnumMeta):
'''
An enumeration where strings can equal the value.
An enumeration where strings can equal the value, and strings
can be found "in" the enum.
See :class:`music21.common.enums.OffsetSpecial` for an
example of how these work.
example of how subclassing this would work.
* Note: This class predates the equivalent StrEnum in Python 3.11
and the changes to Enum `__contains__` in 3.12. Once
Python 3.12 is the minimum version of music21, this class
will no longer be used internally and will eventually become
deprecated (2027?) and removed (2030?).
'''
def __repr__(self):
return f'<{self.__class__.__name__}.{self.name}>'
Expand Down Expand Up @@ -139,8 +146,6 @@ class OffsetSpecial(StrEnum):
The enum `AT_END` is equal to the string 'highestTime'
In version 9, the string comparisons will be removed.
>>> from music21.common.enums import OffsetSpecial
>>> OffsetSpecial.AT_END
<OffsetSpecial.AT_END>
Expand All @@ -156,6 +161,13 @@ class OffsetSpecial(StrEnum):
'highestTime'
* New in v7.
* Note -- a previous note said that the 'highestTime' == OffsetSpecial.AT_END
would be removed in v9 or an upcoming music21 release. Since then, Python has
changed direction and in 3.11 added StrEnum to the standard library and in 3.12
allows for containment checks of strings in StrEnum (such as
`'lowestOffset' in OffsetSpecial` returning True). Therefore there is no
reason for music21 to ever remove this valuable and backwards compatible
tool.
'''
AT_END = 'highestTime'
LOWEST_OFFSET = 'lowestOffset'
Expand Down
4 changes: 2 additions & 2 deletions music21/common/numberTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,11 @@ def _preFracLimitDenominator(n: int, d: int) -> tuple[int, int]:

@overload
def opFrac(num: int) -> float:
pass
...

@overload
def opFrac(num: float|Fraction) -> float|Fraction:
pass
...

# no type checking due to accessing protected attributes (for speed)
def opFrac(num: OffsetQLIn) -> OffsetQL:
Expand Down
8 changes: 4 additions & 4 deletions music21/common/pathTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,22 +154,22 @@ def relativepath(path: StrOrPath, start: str|None = None) -> StrOrPath|str:
@overload
def cleanpath(path: pathlib.Path, *,
returnPathlib: t.Literal[None] = None) -> pathlib.Path:
return pathlib.Path('/') # dummy until Astroid #1015 is fixed.
...

@overload
def cleanpath(path: str, *,
returnPathlib: t.Literal[None] = None) -> str:
return '/' # dummy until Astroid #1015 is fixed.
...

@overload
def cleanpath(path: str|pathlib.Path, *,
returnPathlib: t.Literal[True]) -> pathlib.Path:
return pathlib.Path('/') # dummy until Astroid #1015 is fixed.
...

@overload
def cleanpath(path: str|pathlib.Path, *,
returnPathlib: t.Literal[False]) -> str:
return '/' # dummy until Astroid #1015 is fixed.
...

def cleanpath(path: str|pathlib.Path, *,
returnPathlib: bool|None = None) -> str|pathlib.Path:
Expand Down
4 changes: 2 additions & 2 deletions music21/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -1004,11 +1004,11 @@ def getSettingsPath(self):

@overload
def getTempFile(self, suffix: str, returnPathlib: t.Literal[False]) -> str:
return '/' # astroid #1015
...

@overload
def getTempFile(self, suffix: str = '', returnPathlib: t.Literal[True] = True) -> pathlib.Path:
return pathlib.Path('/') # astroid #1015
...

def getTempFile(self, suffix: str = '', returnPathlib=True) -> str|pathlib.Path:
'''
Expand Down
12 changes: 9 additions & 3 deletions music21/graph/axis.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import collections
import math
import re
import typing as t
import unittest

from music21.graph.utilities import accidentalLabelToUnicode, GraphException
Expand All @@ -35,6 +36,10 @@
from music21.analysis import pitchAnalysis


if t.TYPE_CHECKING:
from music21 import note


USE_GRACE_NOTE_SPACING = -1


Expand Down Expand Up @@ -180,7 +185,7 @@ def stream(self):
else:
return c.streamObj

def extractOneElement(self, n, formatDict):
def extractOneElement(self, n: note.GeneralNote, formatDict: dict[str, t.Any]) -> t.Any:
'''
Override in subclasses
'''
Expand Down Expand Up @@ -319,7 +324,7 @@ def __init__(self, client=None, axisName='x'):
self.hideUnused = True

@staticmethod
def makePitchLabelsUnicode(ticks):
def makePitchLabelsUnicode(ticks: list[tuple[t.Any, str]]) -> list[tuple[t.Any, str]]:
# noinspection PyShadowingNames
'''
Given a list of ticks, replace all labels with alternative/unicode symbols where necessary.
Expand Down Expand Up @@ -452,9 +457,10 @@ def __init__(self, client=None, axisName='x'):
self.minValue = 0
self.maxValue = 11

def extractOneElement(self, n, formatDict):
def extractOneElement(self, n, formatDict) -> int|None:
if hasattr(n, 'pitch'):
return n.pitch.pitchClass
return None

def ticks(self):
'''
Expand Down
14 changes: 14 additions & 0 deletions music21/graph/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,8 @@ def postProcessData(self):
# sort these tuples, ignoring unhashable dict.
v.sort(key=lambda point: (point[0], point[1]))


# seen_numericValues = set()
for numericValue, label in yTicks:
# make sure there is an entry for each yTick, regardless
# of whether we have any data for it or not.
Expand All @@ -1147,6 +1149,18 @@ def postProcessData(self):
dictOfFormatDicts[numericValue]])
else:
newData.append([label, [], {}])
# seen_numericValues.add(numericValue)

# # now find anything in pitchSpanDict that wasn't in the yTicks, for
# # instance, microtones!
# for numericValue, data_triplet in pitchSpanDict.items():
# if numericValue not in seen_numericValues:
# newData.append([
# '', # no label
# data_triplet,
# dictOfFormatDicts[numericValue],
# ])

self.data = newData


Expand Down
Loading

0 comments on commit 62b0bf4

Please sign in to comment.