From 1097e77c11318091f746f411dbd82bd2e424b504 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Thu, 23 Jan 2025 10:44:09 -1000 Subject: [PATCH] Astroid 1015 + misc improvements jan upgrade astroid and get better information about overloads -- this was a long-awaited improvement. Thanks to @jacobtylerwalls for the mypy contributions! some attempts at fixes of graph for microtonal but no work there. Information about deprecation of StrEnum in the distant future --- music21/base.py | 14 +++--- music21/chord/__init__.py | 67 ++++++++++++++------------- music21/common/enums.py | 20 ++++++-- music21/common/numberTools.py | 4 +- music21/common/pathTools.py | 8 ++-- music21/environment.py | 4 +- music21/graph/axis.py | 12 +++-- music21/graph/plot.py | 14 ++++++ music21/graph/primitives.py | 11 +++-- music21/key.py | 8 ++-- music21/note.py | 5 +- music21/pitch.py | 8 ++-- music21/sites.py | 5 +- music21/stream/base.py | 32 ++++--------- music21/stream/iterator.py | 87 ++++++++++++++--------------------- music21/tree/verticality.py | 7 +-- requirements_dev.txt | 3 +- 17 files changed, 153 insertions(+), 156 deletions(-) diff --git a/music21/base.py b/music21/base.py index d542c3ae6..8e97727f0 100644 --- a/music21/base.py +++ b/music21/base.py @@ -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( @@ -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, @@ -1332,7 +1331,7 @@ def getContextByClass( followDerivation=True, priorityTargetOnly=False, ) -> _M21T|None: - return None # until Astroid #1015 + ... @overload def getContextByClass( @@ -1344,7 +1343,7 @@ def getContextByClass( followDerivation=True, priorityTargetOnly=False, ) -> Music21Object|None: - return None # until Astroid #1015 + ... def getContextByClass( self, @@ -1830,7 +1829,7 @@ def contextSites( followDerivation=True, priorityTargetOnly=False, ) -> Generator[ContextSortTuple, None, None]: - pass + ... @overload def contextSites( @@ -1845,8 +1844,7 @@ def contextSites( followDerivation=True, priorityTargetOnly=False, ) -> Generator[ContextTuple, None, None]: - pass - + ... def contextSites( self, diff --git a/music21/chord/__init__.py b/music21/chord/__init__.py index 99373fb91..91803838c 100644 --- a/music21/chord/__init__.py +++ b/music21/chord/__init__.py @@ -1113,7 +1113,7 @@ def annotateIntervals( sortPitches: bool = True, returnList: t.Literal[True] ) -> list[str]: - pass + ... @overload def annotateIntervals( @@ -1124,7 +1124,7 @@ def annotateIntervals( sortPitches: bool = True, returnList: t.Literal[False] = False ) -> None: - pass + ... @overload def annotateIntervals( @@ -1135,7 +1135,7 @@ def annotateIntervals( sortPitches: bool = True, returnList: t.Literal[False] = False ) -> _ChordType: - pass + ... def annotateIntervals( self: _ChordType, @@ -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: @@ -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( @@ -1496,8 +1498,7 @@ def closedPosition( inPlace: t.Literal[False] = False, leaveRedundantPitches: bool = False ) -> _ChordType: - # astroid 1003 - return self + ... def closedPosition( self: _ChordType, @@ -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( @@ -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, @@ -3799,7 +3800,7 @@ def root(self, *, find: bool|None = None ) -> pitch.Pitch: - return self.pitches[0] # dummy until Astroid 1015 is fixed. + ... @overload def root(self, @@ -3807,7 +3808,7 @@ def root(self, *, find: bool|None = None ) -> None: - return None # dummy until Astroid 1015 is fixed. + ... def root(self, newroot: None|str|pitch.Pitch|note.Note = None, diff --git a/music21/common/enums.py b/music21/common/enums.py index f23347ffc..aa8af8e23 100644 --- a/music21/common/enums.py +++ b/music21/common/enums.py @@ -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}>' @@ -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 @@ -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' diff --git a/music21/common/numberTools.py b/music21/common/numberTools.py index 0a708219d..18c4513f6 100644 --- a/music21/common/numberTools.py +++ b/music21/common/numberTools.py @@ -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: diff --git a/music21/common/pathTools.py b/music21/common/pathTools.py index 2a50dcdf0..13819ccb9 100644 --- a/music21/common/pathTools.py +++ b/music21/common/pathTools.py @@ -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: diff --git a/music21/environment.py b/music21/environment.py index 0987d1b94..9dd0285b0 100644 --- a/music21/environment.py +++ b/music21/environment.py @@ -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: ''' diff --git a/music21/graph/axis.py b/music21/graph/axis.py index 55b1fe269..adcfd3cc1 100644 --- a/music21/graph/axis.py +++ b/music21/graph/axis.py @@ -19,6 +19,7 @@ import collections import math import re +import typing as t import unittest from music21.graph.utilities import accidentalLabelToUnicode, GraphException @@ -35,6 +36,10 @@ from music21.analysis import pitchAnalysis +if t.TYPE_CHECKING: + from music21 import note + + USE_GRACE_NOTE_SPACING = -1 @@ -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 ''' @@ -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. @@ -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): ''' diff --git a/music21/graph/plot.py b/music21/graph/plot.py index b1cf52b20..4185f9ac9 100644 --- a/music21/graph/plot.py +++ b/music21/graph/plot.py @@ -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. @@ -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 diff --git a/music21/graph/primitives.py b/music21/graph/primitives.py index 4e89bc920..7438cfd68 100644 --- a/music21/graph/primitives.py +++ b/music21/graph/primitives.py @@ -984,7 +984,7 @@ def renderSubplot(self, subplot) -> None: self.figure.subplots_adjust(left=0.15) yPos = 0 - xPoints = [] # store all to find min/max + xPoints: set[int|float] = set() # store all to find min/max yTicks = [] # a list of label, value pairs xTicks = [] @@ -1028,15 +1028,18 @@ def renderSubplot(self, subplot) -> None: xEnd = xStart + xLen for x in [xStart, xEnd]: if x not in xPoints: - xPoints.append(x) + xPoints.add(x) # ticks are value, label yTicks.append([yPos + self.barSpace * 0.5, key]) # yTicks.append([key, yPos + self.barSpace * 0.5]) yPos += self.barSpace i += 1 - xMin = min(xPoints) - xMax = max(xPoints) + xMin: int|float = 0.0 + xMax: int | float = 0.0 + if xPoints: # do not crash on empty streams + xMin = min(xPoints) + xMax = max(xPoints) xRange = xMax - xMin # environLocal.printDebug(['got xMin, xMax for points', xMin, xMax, ]) diff --git a/music21/key.py b/music21/key.py index 5085835c4..4953d17ce 100644 --- a/music21/key.py +++ b/music21/key.py @@ -665,14 +665,14 @@ def transpose(self: KeySignatureType, value: TransposeTypes, *, inPlace: t.Literal[False] = False) -> KeySignatureType: - return self # astroid 1015 + ... @overload def transpose(self: KeySignatureType, value: TransposeTypes, *, inPlace: t.Literal[True]) -> None: - return None # astroid 1015 + ... def transpose(self: KeySignatureType, value: TransposeTypes, @@ -1237,7 +1237,7 @@ def transpose(self: KeyType, *, inPlace: t.Literal[False] = False ) -> KeyType: - return self # astroid 1015 + ... @overload def transpose(self: KeyType, @@ -1245,7 +1245,7 @@ def transpose(self: KeyType, *, inPlace: t.Literal[True] ) -> None: - return None + ... def transpose(self: KeyType, value: TransposeTypes, diff --git a/music21/note.py b/music21/note.py index 1ba2e7dd3..d00d018e2 100644 --- a/music21/note.py +++ b/music21/note.py @@ -1344,15 +1344,14 @@ def getInstrument(self, *, returnDefault: t.Literal[True] = True ) -> instrument.Instrument: - from music21 import instrument - return instrument.Instrument() # astroid #1015 + ... @overload def getInstrument(self, *, returnDefault: t.Literal[False] ) -> instrument.Instrument|None: - return None # astroid #1015 + ... def getInstrument(self, *, diff --git a/music21/pitch.py b/music21/pitch.py index 634edb772..bccbed61d 100644 --- a/music21/pitch.py +++ b/music21/pitch.py @@ -4019,13 +4019,13 @@ def isEnharmonic(self, other: Pitch) -> bool: def _getEnharmonicHelper(self: PitchType, inPlace: t.Literal[True], up: bool) -> None: - return None # astroid 1015 + ... @overload def _getEnharmonicHelper(self: PitchType, inPlace: t.Literal[False], up: bool) -> PitchType: - return self # astroid 1015 + ... def _getEnharmonicHelper(self: PitchType, inPlace: bool, @@ -4519,7 +4519,7 @@ def transpose( *, inPlace: t.Literal[True] ) -> None: - return None # dummy until Astroid 1015 + ... @overload def transpose( @@ -4528,7 +4528,7 @@ def transpose( *, inPlace: t.Literal[False] = False ) -> PitchType: - return self # dummy until Astroid 1015 + ... def transpose( self: PitchType, diff --git a/music21/sites.py b/music21/sites.py index 6b24f00e5..cfcd1f542 100644 --- a/music21/sites.py +++ b/music21/sites.py @@ -400,8 +400,7 @@ def yieldSites(self, sortByCreationTime: t.Union[bool, t.Literal['reverse']] = False, priorityTarget=None, ) -> Generator[stream.Stream, None, None]: - from music21 import stream - yield stream.Stream() + ... @overload def yieldSites(self, @@ -410,7 +409,7 @@ def yieldSites(self, sortByCreationTime: t.Union[bool, t.Literal['reverse']] = False, priorityTarget=None, ) -> Generator[stream.Stream|None, None, None]: - yield None + ... def yieldSites(self, *, diff --git a/music21/stream/base.py b/music21/stream/base.py index 04d1293a2..bb8b0f53a 100644 --- a/music21/stream/base.py +++ b/music21/stream/base.py @@ -476,44 +476,36 @@ def iter(self) -> iterator.StreamIterator[M21ObjType]: @overload def __getitem__(self, k: str) -> iterator.RecursiveIterator[M21ObjType]: - # Remove this code and replace with ... once Astroid #1015 is fixed. - x: iterator.RecursiveIterator[M21ObjType] = self.recurse() - return x + ... @overload def __getitem__(self, k: int) -> M21ObjType: - return self[k] # dummy code + ... @overload def __getitem__(self, k: slice) -> list[M21ObjType]: - return list(self.elements) # dummy code + ... @overload def __getitem__( self, k: type[ChangedM21ObjType] ) -> iterator.RecursiveIterator[ChangedM21ObjType]: - x = t.cast(iterator.RecursiveIterator[ChangedM21ObjType], self.recurse()) - return x # dummy code + ... @overload def __getitem__( self, k: type # getting something that is a subclass of something that is not a m21 object ) -> iterator.RecursiveIterator[M21ObjType]: - x = t.cast(iterator.RecursiveIterator[M21ObjType], self.recurse()) - return x # dummy code - + ... @overload def __getitem__( self, k: Collection[type] ) -> iterator.RecursiveIterator[M21ObjType]: - # Remove this code and replace with ... once Astroid #1015 is fixed. - x: iterator.RecursiveIterator[M21ObjType] = self.recurse() - return x - + ... def __getitem__(self, k: t.Union[str, @@ -3585,25 +3577,19 @@ def addGroupForElements(self, def getElementsByClass(self, classFilterList: str|Iterable[str] ) -> iterator.StreamIterator[M21ObjType]: - # Remove all dummy code once Astroid #1015 is fixed - x: iterator.StreamIterator[M21ObjType] = self.iter() - return x # dummy code + ... @overload def getElementsByClass(self, classFilterList: type[ChangedM21ObjType] ) -> iterator.StreamIterator[ChangedM21ObjType]: - x: iterator.StreamIterator[ChangedM21ObjType] = ( - self.iter().getElementsByClass(classFilterList) - ) - return x # dummy code + ... @overload def getElementsByClass(self, classFilterList: Iterable[type[ChangedM21ObjType]] ) -> iterator.StreamIterator[M21ObjType]: - x: iterator.StreamIterator[M21ObjType] = self.iter() - return x # dummy code + ... def getElementsByClass(self, classFilterList: t.Union[ diff --git a/music21/stream/iterator.py b/music21/stream/iterator.py index e545e8fe2..b913ce4ca 100644 --- a/music21/stream/iterator.py +++ b/music21/stream/iterator.py @@ -35,7 +35,8 @@ from music21.sites import SitesException if t.TYPE_CHECKING: - from music21 import stream + # need to call this streamModule since we have methods named stream. + from music21 import stream as streamModule T = t.TypeVar('T') S = t.TypeVar('S') @@ -51,7 +52,7 @@ class StreamIteratorInefficientWarning(UserWarning): class ActiveInformation(t.TypedDict, total=False): - stream: stream.Stream|None + stream: streamModule.Stream|None elementIndex: int iterSection: t.Literal['_elements', '_endElements'] sectionIndex: int @@ -779,7 +780,7 @@ def matchesFilters(self, e: base.Music21Object) -> bool: raise # clearer this way to see that this can happen return True - def _newBaseStream(self) -> stream.Stream: + def _newBaseStream(self) -> streamModule.Stream: ''' Returns a new stream.Stream. The same thing as calling: @@ -798,19 +799,24 @@ def _newBaseStream(self) -> stream.Stream: return stream.Stream() @overload - def stream(self, returnStreamSubClass: t.Literal[False]) -> stream.Stream: - # ignore this code -- just here until Astroid bug #1015 is fixed - x: stream.Stream = self.streamObj - return x + def stream(self, returnStreamSubClass: t.Literal[False]) -> streamModule.Stream: + ... @overload def stream(self, returnStreamSubClass: t.Literal[True] = True) -> StreamType: # type: ignore - # Astroid bug + new mypy 0.981 problem -- if type-var is a problem here, then - # it should be in the non-overloaded function below. + # even after Astroid PR 1015 was fixed, Astroid/mypy since (0.981) reports + # an error (even with this dummy code) saying that it cannot get a StreamType, + # A function returning TypeVar should receive at least + # one argument containing the same TypeVar + # But if this were the case then the following method would have the same problem. x: StreamType = self.streamObj return x - def stream(self, returnStreamSubClass=True) -> stream.Stream|StreamType: + + def stream( + self, + returnStreamSubClass: bool = True + ) -> streamModule.Stream|StreamType: ''' return a new stream from this iterator. @@ -879,7 +885,7 @@ def stream(self, returnStreamSubClass=True) -> stream.Stream|StreamType: # if this stream was sorted, the resultant stream is sorted clearIsSorted = False - found: stream.Stream|StreamType + found: streamModule.Stream|StreamType if returnStreamSubClass is True: try: found = ss.__class__() @@ -1006,51 +1012,40 @@ def getElementById(self, elementId: str) -> M21ObjType|None: return e return None - # Replace all code in overload statements once - # https://github.com/PyCQA/astroid/issues/1015 - # is fixed and deployed @overload def getElementsByClass(self, classFilterList: str, *, returnClone: bool = True) -> StreamIterator[M21ObjType]: - x: StreamIterator[M21ObjType] = self.__class__(self.streamObj) - return x + ... @overload def getElementsByClass(self, classFilterList: Iterable[str], *, returnClone: bool = True) -> StreamIterator[M21ObjType]: - x: StreamIterator[M21ObjType] = self.__class__(self.streamObj) - return x + ... # @overload # def getElementsByClass(self, # classFilterList: type, # *, # returnClone: bool = True) -> StreamIterator[M21ObjType]: - # # putting a non-music21 type into classFilterList, defaults to the previous type - # x: StreamIterator[M21ObjType] = self.__class__(self.streamObj) - # return x + # ... @overload def getElementsByClass(self, classFilterList: type[ChangedM21ObjType], *, returnClone: bool = True) -> StreamIterator[ChangedM21ObjType]: - x = t.cast(StreamIterator[ChangedM21ObjType], self.__class__(self.streamObj)) - return x + ... @overload def getElementsByClass(self, classFilterList: Iterable[type], *, returnClone: bool = True) -> StreamIterator[M21ObjType]: - # putting multiple types into classFilterList, defaults to the previous type - x: StreamIterator[M21ObjType] = self.__class__(self.streamObj) - return x - + ... def getElementsByClass( self, @@ -1654,50 +1649,41 @@ def reset(self): # NOTE: these getElementsByClass are the same as the one in StreamIterator, but # for now it needs to be duplicated until changing a Generic's argument type - # can be done with inheritance. - # TODO: remove code and replace with ... when Astroid bug #1015 is fixed. - + # can be done with inheritance (Higher-Kinded Types). @overload def getElementsByClass(self, classFilterList: str, *, returnClone: bool = True) -> OffsetIterator[M21ObjType]: - x: OffsetIterator[M21ObjType] = self.__class__(self.streamObj) - return x + ... @overload def getElementsByClass(self, classFilterList: Iterable[str], *, returnClone: bool = True) -> OffsetIterator[M21ObjType]: - x: OffsetIterator[M21ObjType] = self.__class__(self.streamObj) - return x + ... @overload def getElementsByClass(self, classFilterList: type[ChangedM21ObjType], *, returnClone: bool = True) -> OffsetIterator[ChangedM21ObjType]: - x = t.cast(OffsetIterator[ChangedM21ObjType], self.__class__(self.streamObj)) - return x + ... # @overload # def getElementsByClass(self, # classFilterList: type, # *, # returnClone: bool = True) -> OffsetIterator[M21ObjType]: - # x: OffsetIterator[M21ObjType] = self.__class__(self.streamObj) - # return x - + # ... @overload def getElementsByClass(self, classFilterList: Iterable[type], *, returnClone: bool = True) -> OffsetIterator[M21ObjType]: - x: OffsetIterator[M21ObjType] = self.__class__(self.streamObj) - return x - + ... def getElementsByClass(self, classFilterList: t.Union[ @@ -1861,7 +1847,7 @@ def __next__(self) -> M21ObjType: # only the internal elements. if e.isStream: if t.TYPE_CHECKING: - assert isinstance(e, stream.Stream) + assert isinstance(e, streamModule.Stream) childRecursiveIterator: RecursiveIterator[M21ObjType] = RecursiveIterator( srcStream=e, @@ -2073,40 +2059,35 @@ def getElementsByClass(self, classFilterList: str, *, returnClone: bool = True) -> RecursiveIterator[M21ObjType]: - x: RecursiveIterator[M21ObjType] = self.__class__(self.streamObj) - return x # dummy code remove when Astroid #1015 is fixed. + ... @overload def getElementsByClass(self, classFilterList: Iterable[str], *, returnClone: bool = True) -> RecursiveIterator[M21ObjType]: - x: RecursiveIterator[M21ObjType] = self.__class__(self.streamObj) - return x # dummy code + ... @overload def getElementsByClass(self, classFilterList: type[ChangedM21ObjType], *, returnClone: bool = True) -> RecursiveIterator[ChangedM21ObjType]: - x = t.cast(RecursiveIterator[ChangedM21ObjType], self.__class__(self.streamObj)) - return x # dummy code + ... # @overload # def getElementsByClass(self, # classFilterList: type, # *, # returnClone: bool = True) -> RecursiveIterator[M21ObjType]: - # x: RecursiveIterator[M21ObjType] = self.__class__(self.streamObj) - # return x # dummy code + # ... @overload def getElementsByClass(self, classFilterList: Iterable[type], *, returnClone: bool = True) -> RecursiveIterator[M21ObjType]: - x: RecursiveIterator[M21ObjType] = self.__class__(self.streamObj) - return x # dummy code + ... def getElementsByClass(self, diff --git a/music21/tree/verticality.py b/music21/tree/verticality.py index 50f9eeacc..18bb43c16 100644 --- a/music21/tree/verticality.py +++ b/music21/tree/verticality.py @@ -959,8 +959,7 @@ def getAllVoiceLeadingQuartets( returnObjects: t.Literal[False], partPairNumbers: list[tuple[int, int]] | None = None ) -> list[PitchedTimespanQuartet]: - # dummy until Astroid #1015 is fixed. Replace with ... - return [] + ... @overload def getAllVoiceLeadingQuartets( @@ -972,9 +971,7 @@ def getAllVoiceLeadingQuartets( returnObjects: t.Literal[True] = True, partPairNumbers: list[tuple[int, int]] | None = None ) -> list[VoiceLeadingQuartet]: - # dummy until Astroid #1015 is fixed. Replace with ... - return [] - + ... def getAllVoiceLeadingQuartets( self, diff --git a/requirements_dev.txt b/requirements_dev.txt index a4036d5ea..f2f4ebf11 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,10 +1,11 @@ -r requirements.txt wheel +astroid>=3.2.0 pylint>=2.16.0 flake8<7.0.0 flake8-quotes>=3.3.2 hatchling -mypy>=1.4.0 +mypy>=1.13.0 coveralls scipy sphinx