From dc3ee80705eb01b4b72a17b9b9c8e2df9b08ee5f Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 28 Oct 2024 14:56:56 -1000 Subject: [PATCH 1/3] Remove tons of ellipses There were a number of places in the code where ellipses were being used to hide differences among Python versions (we added two more to turn on 3.13 just now). Remove places that were still being used for differences with 3.9 and below (including some 2.7!) And just generally get out of the old sloppy habit of using ... instead of knowing what the sentence actually says. --- .idea/encodings.xml | 4 +- dist/dist.py | 6 +- documentation/docbuild/documenters.py | 4 +- documentation/docbuild/upload.py | 2 +- documentation/docbuild/writers.py | 2 +- documentation/testDocumentation.py | 2 +- music21/__init__.py | 2 +- music21/abcFormat/__init__.py | 6 +- music21/abcFormat/translate.py | 8 +- music21/analysis/discrete.py | 6 +- music21/analysis/floatingKey.py | 2 +- music21/analysis/reduceChords.py | 2 +- music21/analysis/reduceChordsOld.py | 4 +- music21/analysis/windowed.py | 6 +- music21/articulations.py | 4 +- music21/audioSearch/__init__.py | 12 +-- music21/audioSearch/scoreFollower.py | 6 +- music21/bar.py | 2 +- music21/base.py | 62 ++++++----- music21/beam.py | 2 +- music21/braille/basic.py | 4 +- music21/braille/noteGrouping.py | 10 +- music21/braille/runAllBrailleTests.py | 2 +- music21/braille/segment.py | 14 +-- music21/braille/text.py | 2 +- music21/capella/fromCapellaXML.py | 6 +- music21/chord/__init__.py | 68 ++++++------ music21/clef.py | 4 +- music21/common/decorators.py | 11 +- music21/common/formats.py | 4 +- music21/common/misc.py | 12 ++- music21/common/numberTools.py | 24 ++--- music21/common/objects.py | 2 +- music21/common/stringTools.py | 4 +- music21/common/weakrefTools.py | 7 ++ music21/configure.py | 2 +- music21/converter/__init__.py | 16 +-- music21/converter/subConverters.py | 2 +- music21/corpus/chorales.py | 4 +- music21/corpus/corpora.py | 10 +- music21/corpus/manager.py | 6 +- music21/corpus/work.py | 5 +- music21/defaults.py | 4 +- music21/derivation.py | 2 +- music21/duration.py | 46 ++++---- music21/editorial.py | 8 ++ music21/environment.py | 6 +- music21/exceptions21.py | 2 +- music21/expressions.py | 2 +- music21/features/base.py | 6 +- music21/features/jSymbolic.py | 4 +- music21/figuredBass/realizer.py | 4 +- music21/freezeThaw.py | 28 ++--- music21/graph/__init__.py | 2 +- music21/graph/axis.py | 12 +-- music21/graph/findPlot.py | 18 ++-- music21/graph/plot.py | 6 +- music21/graph/primitives.py | 6 +- music21/graph/utilities.py | 4 +- music21/harmony.py | 28 +++-- music21/humdrum/__init__.py | 2 +- music21/humdrum/questions.py | 8 +- music21/humdrum/spineParser.py | 44 ++++---- music21/instrument.py | 13 +-- music21/interval.py | 20 ++-- music21/key.py | 2 +- music21/languageExcerpts/instrumentLookup.py | 2 +- music21/layout.py | 9 +- music21/lily/lilyObjects.py | 19 ++-- music21/lily/translate.py | 64 ++++++------ music21/mei/base.py | 8 +- music21/mei/test_base.py | 20 ++-- music21/metadata/__init__.py | 6 +- music21/metadata/bundles.py | 2 +- music21/metadata/caching.py | 2 +- music21/metadata/primitives.py | 8 +- music21/metadata/properties.py | 2 +- music21/meter/base.py | 18 ++-- music21/meter/core.py | 12 +-- music21/meter/tools.py | 4 +- music21/midi/__init__.py | 6 +- music21/midi/percussion.py | 2 +- music21/midi/translate.py | 4 +- music21/musedata/__init__.py | 44 ++++++-- music21/musedata/base40.py | 2 +- music21/musedata/testPrimitive/test01/01.md | 4 +- music21/musedata/testPrimitive/test01/02.md | 4 +- music21/musedata/testPrimitive/test01/03.md | 2 +- music21/musedata/testPrimitive/test01/04.md | 2 +- music21/musedata/testPrimitive/test01/05.md | 4 +- music21/musedata/translate.py | 2 +- music21/musicxml/archiveTools.py | 2 +- music21/musicxml/helpers.py | 4 +- music21/musicxml/m21ToXml.py | 104 ++++++++++--------- music21/musicxml/testPrimitive.py | 2 +- music21/musicxml/test_xmlToM21.py | 16 +-- music21/musicxml/xmlObjects.py | 6 +- music21/musicxml/xmlToM21.py | 90 ++++++++-------- music21/note.py | 12 ++- music21/noteworthy/binaryTranslate.py | 4 +- music21/noteworthy/translate.py | 8 +- music21/omr/correctors.py | 2 +- music21/omr/evaluators.py | 6 +- music21/pitch.py | 32 +++--- music21/repeat.py | 4 +- music21/roman.py | 46 ++++---- music21/romanText/clercqTemperley.py | 6 +- music21/romanText/rtObjects.py | 7 +- music21/romanText/translate.py | 14 +-- music21/romanText/tsvConverter.py | 2 +- music21/scale/__init__.py | 10 +- music21/scale/scala/__init__.py | 4 +- music21/search/base.py | 6 +- music21/search/serial.py | 4 +- music21/sieve.py | 4 +- music21/sites.py | 13 ++- music21/spanner.py | 2 +- music21/stream/base.py | 89 ++++++++-------- music21/stream/core.py | 6 +- music21/stream/filters.py | 6 +- music21/stream/iterator.py | 26 ++--- music21/stream/makeNotation.py | 10 +- music21/stream/tests.py | 24 ++--- music21/tablature.py | 2 +- music21/test/commonTest.py | 12 +-- music21/test/multiprocessTest.py | 4 +- music21/test/testLint.py | 32 +++--- music21/test/testRunner.py | 4 +- music21/test/testSerialization.py | 4 +- music21/test/testSingleCoreAll.py | 2 +- music21/test/test_base.py | 14 +-- music21/test/test_metadata.py | 2 +- music21/test/toggleDebug.py | 2 +- music21/test/treeYield.py | 6 +- music21/test/warningMultiprocessTest.py | 2 +- music21/tie.py | 2 +- music21/tinyNotation.py | 2 +- music21/tree/core.py | 6 +- music21/tree/fromStream.py | 4 +- music21/tree/spans.py | 4 +- music21/tree/timespanTree.py | 12 +-- music21/tree/trees.py | 23 ++-- music21/tree/verticality.py | 6 +- music21/variant.py | 6 +- music21/vexflow/toMusic21j.py | 4 +- music21/voiceLeading.py | 9 +- music21/volume.py | 4 +- 147 files changed, 848 insertions(+), 783 deletions(-) diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 15a15b218a..58465bc112 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,4 +1,6 @@ - + + + \ No newline at end of file diff --git a/dist/dist.py b/dist/dist.py index 1aaaa2846b..f7a29a0224 100644 --- a/dist/dist.py +++ b/dist/dist.py @@ -57,7 +57,7 @@ 15. PR and Commit to GitHub at this point w/ commit comment of the new version, then don't change anything until the next step is done. - (.gitignore will avoid uploading the large files created here...) + (.gitignore will avoid uploading the large files created here.) 16. Switch back to master/main branch @@ -71,7 +71,7 @@ Drag in this order: .tar.gz, -docs.zip, no-corpus.tar.gz Finish this before doing the next step, even though it looks like it could be done in parallel. - + 20. Upload the new file to PyPI with "twine upload music21-7.3.5a2.tar.gz", and same for the whl file (but NOT no corpus) [*] @@ -87,7 +87,7 @@ username:your_username password:your_password -21. Delete the two .tar.gz files and .whl file in dist... +21. Delete the two .tar.gz files and .whl file in dist. 22. For starting a new major release create a GitHub branch for the old one. diff --git a/documentation/docbuild/documenters.py b/documentation/docbuild/documenters.py index 239bf71869..1fa6273570 100644 --- a/documentation/docbuild/documenters.py +++ b/documentation/docbuild/documenters.py @@ -652,7 +652,7 @@ def inheritedDocAttrMapping(self): ''' # if one of the _DOC_ATTRs is exactly the same as the previous base class, # only show it once. - # TODO: do this on an attribute by attribute basis... + # TODO: do this on an attribute by attribute basis seenBaseClassDocAttrs = [] if self._inheritedDocAttrMapping is None: @@ -1501,7 +1501,7 @@ def run(self): result.extend(self.makeHeading(self.headingText, 1)) result.extend(self.rstEditingWarningFormat) result.extend(self.rstCorpusIntroductionFormat) - # TODO: use... common.getCorpusContentDirs to make sure nothing is missed. + # TODO: use common.getCorpusContentDirs to make sure nothing is missed. for directoryInformation in corpus.corpora.CoreCorpus().getWorkReferences(): result.extend(self.getRstComposerDictFormat(directoryInformation)) return result diff --git a/documentation/docbuild/upload.py b/documentation/docbuild/upload.py index ae47f0654a..12cbecf46c 100644 --- a/documentation/docbuild/upload.py +++ b/documentation/docbuild/upload.py @@ -47,7 +47,7 @@ eval "${SCRIPT}"; -Otherwise just contact MSC... +Otherwise just contact MSAC. ''' from __future__ import annotations diff --git a/documentation/docbuild/writers.py b/documentation/docbuild/writers.py index 56210424d3..9e1e4a4904 100644 --- a/documentation/docbuild/writers.py +++ b/documentation/docbuild/writers.py @@ -134,7 +134,7 @@ def write(self, filePath, rst): shouldWrite = False else: pass - # # uncomment for help in figuring out why a file keeps being different... + # # uncomment for help in figuring out why a file keeps being different # import difflib # print(common.relativepath(filePath)) # print('\n'.join(difflib.ndiff(rst.split('\n'), oldRst.split('\n')))) diff --git a/documentation/testDocumentation.py b/documentation/testDocumentation.py index 4d9d97e12f..4236f26c63 100644 --- a/documentation/testDocumentation.py +++ b/documentation/testDocumentation.py @@ -169,7 +169,7 @@ def getDocumentationFiles(runOne=False): fullModulePath = os.path.join(root, module) if not module.endswith('.rst'): continue - if module.startswith('module'): # we have this already... + if module.startswith('module'): # we have this already continue if module in skipModules: continue diff --git a/music21/__init__.py b/music21/__init__.py index 6d5d93cc58..aca185ffb1 100644 --- a/music21/__init__.py +++ b/music21/__init__.py @@ -83,7 +83,7 @@ 'mainTest', 'prebase', # before all - 'base', # top... + 'base', # top 'sites', # important # sub folders diff --git a/music21/abcFormat/__init__.py b/music21/abcFormat/__init__.py index 91477a101a..27f4fbed0c 100644 --- a/music21/abcFormat/__init__.py +++ b/music21/abcFormat/__init__.py @@ -724,7 +724,7 @@ def getMetronomeMarkObject(self) -> tempo.MetronomeMark|None: else: # this is an error case environLocal.printDebug(['incorrectly encoded / unparsable duration:', dur]) n, d = '1', '1' - # n and d might be strings... + # n and d might be strings referent += (float(n) / float(d)) * 4 else: # assume we just have a quarter definition, e.g., Q:90 number = float(nonText) @@ -2323,7 +2323,7 @@ def tokenize(self, strSrc: str) -> None: self.skipAhead = j - self.pos # not + 1 break j += 1 - # not found, continue... + # not found, continue continue # get slurs, ensuring that they're not confused for tuplets @@ -3013,7 +3013,7 @@ def splitByVoice(self) -> list[ABCHandler]: 'D3', 'D3', '|', 'D6', '|', 'D3', 'D3', '|', 'D6', '||'] - Then later the metadata can be merged at the start of each voice... + Then later the metadata can be merged at the start of each voice: >>> mergedTokens = tokenColls[0] + tokenColls[1] >>> mergedTokens diff --git a/music21/abcFormat/translate.py b/music21/abcFormat/translate.py index 2dd07a439d..6b8a8d6300 100644 --- a/music21/abcFormat/translate.py +++ b/music21/abcFormat/translate.py @@ -231,7 +231,7 @@ def abcToStreamPart( try: p.makeBeams(inPlace=True) except (meter.MeterException, stream.StreamException) as e: - environLocal.warn(f'Error in beaming...ignoring: {e}') + environLocal.warn(f'Error in beaming. Ignoring: {e}') # copy spanners into topmost container; here, a part rm = [] @@ -371,7 +371,7 @@ def parseABCNote( n.tie.style = 'normal' elif t.tie == 'stop': n.tie = tie.Tie(t.tie) - # Was: Extremely Slow for large Opus files... why? + # Was: Extremely Slow for large Opus files. Why? # Answer: some pieces didn't close all their spanners, so # everything was in a Slur/Diminuendo, etc. for span in t.applicableSpanners: @@ -587,7 +587,7 @@ def reBar(music21Part, *, inPlace=False): to the last time signature, in this case 2/4. The default is to reBar in place. The measure numbers are updated accordingly. - (NOTE: reBar is called automatically in abcToStreamPart, hence not demonstrated below...) + (NOTE: reBar is called automatically in abcToStreamPart, hence not demonstrated below.) The key signature and clef are assumed to be the same in the second measure after the split, so both are omitted. If the time signature is not the same in the second measure, @@ -1157,7 +1157,7 @@ def testTiesTranslate(self): def xtestMergeScores(self): from music21 import corpus unused = corpus.parse('josquin/laDeplorationDeLaMorteDeJohannesOckeghem') - # this was getting incorrect Clefs... + # this was getting incorrect Clefs if __name__ == '__main__': diff --git a/music21/analysis/discrete.py b/music21/analysis/discrete.py index d32f50f182..41a9124dc8 100644 --- a/music21/analysis/discrete.py +++ b/music21/analysis/discrete.py @@ -1009,9 +1009,9 @@ def getPitchSpan(self, subStream) -> tuple[pitch.Pitch, pitch.Pitch]|None: For a given subStream, return a tuple consisting of the two pitches with the minimum and maximum pitch space value. - This public method may be used by other classes. + This public method may be used by other classes. It ignores ChordSymbol objects. - ignores ChordSymbol objects... + Demonstration: >>> s = corpus.parse('bach/bwv66.6') >>> p = analysis.discrete.Ambitus() @@ -1362,7 +1362,7 @@ def analysisClassFromMethodName(method: str) -> type[DiscreteAnalysis]|None: >>> acfmn('span') - This one is fundamentally important... + This one is fundamentally important: >>> acfmn('key') diff --git a/music21/analysis/floatingKey.py b/music21/analysis/floatingKey.py index 8fa959b637..3b221df00a 100644 --- a/music21/analysis/floatingKey.py +++ b/music21/analysis/floatingKey.py @@ -55,7 +55,7 @@ class KeyAnalyzer: , , , ] - Major smoothing... + Major smoothing: >>> ka.windowSize = ka.numMeasures // 2 >>> ka.run() # only the pickup seems to be in A major by this approach diff --git a/music21/analysis/reduceChords.py b/music21/analysis/reduceChords.py index 6aaf44e5fe..f37ff5f9d1 100644 --- a/music21/analysis/reduceChords.py +++ b/music21/analysis/reduceChords.py @@ -593,7 +593,7 @@ def reduceMeasureToNChords( if currentGreedyChord is not None: currentGreedyChord.quarterLength = currentGreedyChordNewLength currentGreedyChordNewLength = 0.0 - # even chord lengths... + # even chord lengths for i in range(1, len(measureObject)): c = measureObject[i] cOffsetCurrent = c.offset diff --git a/music21/analysis/reduceChordsOld.py b/music21/analysis/reduceChordsOld.py index 886c2180d5..f01eaa1f25 100644 --- a/music21/analysis/reduceChordsOld.py +++ b/music21/analysis/reduceChordsOld.py @@ -53,7 +53,7 @@ def __init__(self): self.positionInMeasure = None self.numberOfElementsInMeasure = None - # for working... + # for working self._lastPitchedObject = None self._lastTs = None @@ -136,7 +136,7 @@ def reduceMeasureToNChords(self, currentGreedyChord.quarterLength = currentGreedyChordNewLength currentGreedyChordNewLength = 0.0 - # even chord lengths... + # even chord lengths for i in range(1, len(mObj)): c = mObj[i] cOffsetCurrent = c.offset diff --git a/music21/analysis/windowed.py b/music21/analysis/windowed.py index 1b1740baea..fd530657a7 100644 --- a/music21/analysis/windowed.py +++ b/music21/analysis/windowed.py @@ -187,7 +187,7 @@ def analyze(self, windowSize, windowType='overlap'): try: data[i], color[i] = self.processor.process(current) except DiscreteAnalysisException: - # current might have no notes...all rests? + # current might have no notes: all rests? data[i], color[i] = (None, None, 0), '#ffffff' elif windowType == 'noOverlap': @@ -203,7 +203,7 @@ def analyze(self, windowSize, windowType='overlap'): try: data[i], color[i] = self.processor.process(current) except DiscreteAnalysisException: - # current might have no notes...all rests? + # current might have no notes: all rests? data[i], color[i] = (None, None, 0), '#ffffff' start = end @@ -232,7 +232,7 @@ def analyze(self, windowSize, windowType='overlap'): try: data[i], color[i] = self.processor.process(current) except DiscreteAnalysisException: - # current might have no notes...all rests? + # current might have no notes: all rests? data[i], color[i] = (None, None, 0), '#ffffff' return data, color diff --git a/music21/articulations.py b/music21/articulations.py index d9d1485790..8fa53055d0 100644 --- a/music21/articulations.py +++ b/music21/articulations.py @@ -283,7 +283,7 @@ class Spiccato(Staccato, Accent): def __init__(self, **keywords): Staccato.__init__(self) with tempAttribute(self, 'lengthShift'): - Accent.__init__(self) # order matters... + Accent.__init__(self) # order matters! class Tenuto(LengthArticulation): @@ -405,7 +405,7 @@ class TechnicalIndication(Articulation): class Harmonic(TechnicalIndication): ''' - A general harmonic indicator -- StringHarmonic is probably what you want... + A general harmonic indicator -- StringHarmonic is probably what you want. ''' class Bowing(TechnicalIndication): diff --git a/music21/audioSearch/__init__.py b/music21/audioSearch/__init__.py index ba358fd62e..f317753553 100644 --- a/music21/audioSearch/__init__.py +++ b/music21/audioSearch/__init__.py @@ -138,7 +138,7 @@ def autocorrelationFunction(recordedSignal, recordSampleRateIn): + f'numpy installed (scipy recommended). Missing {base._missingImport}') import numpy try: - with warnings.catch_warnings(): # scipy.signal gives ImportWarning... + with warnings.catch_warnings(): # scipy.signal gives ImportWarning warnings.simplefilter('ignore', ImportWarning) # numpy warns scipy that oldnumeric will be dropped soon. warnings.simplefilter('ignore', DeprecationWarning) @@ -351,7 +351,7 @@ def getFrequenciesFromMicrophone(length=10.0, storeWaveFilename=None): Returns a list of frequencies detected. - TODO -- find a way to test... or at least demo + TODO -- find a way to test or at least demo ''' if 'numpy' in base._missingImport: raise AudioSearchException( @@ -436,7 +436,7 @@ def getFrequenciesFromPartialAudioFile(waveFilenameOrHandle='temp', length=10.0, >>> print(currentSample) # should be near 44100, but probably not exact 44032 - Now read the next 1 second... + Now read the next 1 second: >>> fTup = audioSearch.getFrequenciesFromPartialAudioFile(pachelbelFileHandle, length=1.0, ... startSample=currentSample) @@ -534,7 +534,7 @@ def smoothFrequencies( Smooths the shape of the signal in order to avoid false detections in the fundamental frequency. Takes in a list of ints or floats. - The second pitch below is obviously too low. It will be smoothed out... + The second pitch below is obviously too low. It will be smoothed out: >>> inputPitches = [440, 220, 440, 440, 442, 443, 441, 470, 440, 441, 440, ... 442, 440, 440, 440, 397, 440, 440, 440, 442, 443, 441, @@ -971,11 +971,11 @@ def decisionProcess( countdown = countdown + 1 elif dist > 20 and countdown == 0: countdown += 1 - environLocal.printDebug(f'Excessive distance....? {dist=}') + environLocal.printDebug(f'Excessive distance? {dist=}') elif dist > 30 and countdown == 1: countdown += 1 - environLocal.printDebug(f'Excessive distance....? {dist=}') + environLocal.printDebug(f'Excessive distance? {dist=}') elif ((firstNotePage is not None and lastNotePage is not None) and ((positionBeginningData < firstNotePage diff --git a/music21/audioSearch/scoreFollower.py b/music21/audioSearch/scoreFollower.py index e53f3e91a3..9b6e6c4555 100644 --- a/music21/audioSearch/scoreFollower.py +++ b/music21/audioSearch/scoreFollower.py @@ -159,7 +159,7 @@ def repeatTranscription(self): notesList, durationList = audioSearch.joinConsecutiveIdenticalPitches( detectedPitchObjects) self.silencePeriodDetection(notesList) - environLocal.printDebug('made it to here...') + environLocal.printDebug('made it to here.') excerpt = self.scoreStream[self.lastNotePosition:self.lastNotePosition + len(notesList)] scNotes = stream.Part(excerpt) # print('1') @@ -178,12 +178,12 @@ def repeatTranscription(self): ) # print('3') self.processing_time = time() - time_start - environLocal.printDebug('and even to here...') + environLocal.printDebug('and even to here.') if END_OF_SCORE is True: exitType = 'endOfScore' # 'endOfScore' return exitType - # estimate position, or exit if we can't at all... + # estimate position, or exit if we can't at all exitType = self.updatePosition(prob, totalLengthPeriod, time_start) if self.useMic is False: # reading from the disc (only for TESTS) diff --git a/music21/bar.py b/music21/bar.py index 2e73ed6cdc..220af30457 100644 --- a/music21/bar.py +++ b/music21/bar.py @@ -136,7 +136,7 @@ def __init__(self, **keywords): super().__init__(**keywords) - self._type = None # same as style... + self._type = None # same as style # this will raise an exception on error from property self.type = type diff --git a/music21/base.py b/music21/base.py index 870de23ebb..b32e1082d3 100644 --- a/music21/base.py +++ b/music21/base.py @@ -76,7 +76,7 @@ _M21T = t.TypeVar('_M21T', bound='music21.base.Music21Object') -# all other music21 modules below... +# all other music21 modules below # ----------------------------------------------------------------------------- # version string and tuple must be the same @@ -132,7 +132,7 @@ class ElementException(exceptions21.Music21Exception): # ----------------------------------------------------------------------------- -# for contextSites searches... +# for contextSites searches class ContextTuple(t.NamedTuple): site: stream.Stream offset: OffsetQL @@ -240,7 +240,7 @@ class Groups(list): # no need to inherit from slotted object # timing: a subclassed list and a set are almost the same speed # and set does not allow calling by number - # this speeds up creation slightly... + # this speeds up creation slightly __slots__ = () def _validName(self, value: str) -> None: @@ -871,9 +871,15 @@ def derivation(self) -> Derivation: >>> n = note.Note() >>> n.derivation from None> + + Make a copy of n but change the pitch to D to see which is which later: + >>> import copy >>> n2 = copy.deepcopy(n) - >>> n2.pitch.step = 'D' # for seeing easier... + >>> n2.pitch.step = 'D' + + Because n2 was originally a copy of n, it has a derivation set to show it. + >>> n2.derivation from via '__deepcopy__'> >>> n2.derivation.origin is n @@ -1000,7 +1006,7 @@ def getOffsetBySite( >>> n3 = note.Note(type='whole') >>> s3.append(n3) >>> rb = bar.Barline() - >>> s3.storeAtEnd(rb) # s3.rightBarline = rb would do the same... + >>> s3.storeAtEnd(rb) # s3.rightBarline = rb would do the same >>> rb.getOffsetBySite(s3) 4.0 @@ -1030,7 +1036,7 @@ def getOffsetBySite( a = site.elementOffset(tryOrigin, returnSpecial=returnSpecial) except AttributeError as ae: raise SitesException( - f'You were using {site!r} as a site, when it is not a Stream...' + f'You were using {site!r} as a site, when it is not a Stream.' ) from ae except Music21Exception as e: # currently StreamException, but will change if tryOrigin in site._endElements: @@ -1047,7 +1053,7 @@ def getOffsetBySite( if id(tryOrigin) in originMemo: raise e originMemo.add(id(tryOrigin)) - maxSearch -= 1 # prevent infinite recursive searches... + maxSearch -= 1 # prevent infinite recursive searches if maxSearch < 0: raise e return a @@ -1159,7 +1165,7 @@ def getOffsetInHierarchy( OMIT_FROM_DOCS Timing: 113microseconds for a search vs 1 microsecond for getOffsetBySite - vs 0.4 for elementOffset. Hence the short-circuit for easy looking below... + vs 0.4 for elementOffset. Hence the short-circuit for easy looking below. TODO: If timing permits, replace .flatten() w/ and w/o retainContainers with this routine. @@ -1310,11 +1316,11 @@ def purgeLocations(self, rescanIsDead=False) -> None: Remove references to all locations in objects that no longer exist. ''' # NOTE: this method is overridden on Spanner - # and Variant, so not an easy fix to remove... + # and Variant, so not an easy fix to remove self.sites.purgeLocations(rescanIsDead=rescanIsDead) # -------------------------------------------------------------------------------- - # contexts... + # contexts @overload def getContextByClass( @@ -1775,7 +1781,7 @@ def wellFormed(checkContextEl, checkSite) -> bool: except SitesException: pass return contextEl - # otherwise, continue to check for flattening... + # otherwise, continue to check for flattening if searchType != 'elementsOnly': # flatten or elementsFirst if (getElementMethod in AFTER_METHODS @@ -1785,7 +1791,7 @@ def wellFormed(checkContextEl, checkSite) -> bool: pass elif getElementMethod not in NOT_SELF_METHODS: # for 'After' we can't do the # containing site because that comes before. - return site # if the site itself is the context, return it... + return site # if the site itself is the context, return it contextEl = payloadExtractor(site, flatten='semiFlat', @@ -1803,11 +1809,11 @@ def wellFormed(checkContextEl, checkSite) -> bool: if getElementMethod in NOT_SELF_METHODS and self is site: pass else: - return site # if the site itself is the context, return it... + return site # if the site itself is the context, return it # otherwise, continue to check in next contextSite. - # nothing found... + # nothing found return None @@ -1855,7 +1861,7 @@ def contextSites( priorityTargetOnly=False, ) -> Generator[ContextTuple|ContextSortTuple, None, None]: ''' - A generator that returns a list of namedtuples of sites to search for a context... + A generator that returns a list of namedtuples of sites to search for a context. Each tuple contains three elements: @@ -1998,7 +2004,7 @@ def contextSites( - We can sort sites by creationTime... + We can sort sites by creationTime: >>> for csTuple in n.contextSites(sortByCreationTime=True): ... print(csTuple.site) @@ -2007,7 +2013,7 @@ def contextSites( - oldest first... + Use `reverse` for oldest first: >>> for csTuple in n.contextSites(sortByCreationTime='reverse'): ... print(csTuple.site) @@ -2226,8 +2232,8 @@ def next(self, >>> nextM3 is m4 True - Note that calling next() repeatedly gives...the same object. You'll want to - call next on that object... + Note that calling next() repeatedly gives the same object. You'll want to + call next on that object. >>> m3.next('Measure') is s.parts[0].measure(4) True @@ -2259,11 +2265,11 @@ def next(self, Notice though that when we get to the end of the set of measures, something - interesting happens (maybe it shouldn't? don't count on this...): we descend + interesting happens (maybe it shouldn't? don't count on this.): we descend into the last measure and give its elements instead. - We'll leave o where it is (m8 now) to demonstrate what happens, and also - print its Part for more information... + We'll leave `o` where it is (m8 now) to demonstrate what happens, and also + print its Part for more information: >>> while o is not None: ... print(o, o.getContextByClass(stream.Part)) @@ -2396,7 +2402,7 @@ def previous(self, return prevEl else: # okay, go up to next level - activeS = self.activeSite # might be None... + activeS = self.activeSite # might be None if activeS is None: return None asTree = activeS.asTree(classList=[className], flatten=False) @@ -2409,7 +2415,7 @@ def previous(self, else: return prevNode.payload - # end contexts... + # end contexts # -------------------------------------------------------------------------------- # ------------------------------------------------------------------------- @@ -2669,7 +2675,7 @@ def sortTuple(self, >>> st = n.sortTuple() - Check that all these values are the same as above... + Check that all these values are the same as above: >>> st.offset == n.offset True @@ -2690,7 +2696,7 @@ def sortTuple(self, Inserting the note into the Stream will set the insertIndex. Most implementations of music21 will use a global counter rather than an actual timer. Note that this is a last resort, but useful for things such as multiple Parts inserted in order. It changes - with each run, so we can't display it here... + with each run, so we can't display it here. >>> s = stream.Stream() >>> s.insert(n) @@ -3159,7 +3165,7 @@ def splitAtQuarterLength( >>> f.pitch.accidental.displayStatus False - Should be the same for chords... + Should be the same for chords: >>> g = chord.Chord(['C4', 'E4', 'G#4']) >>> g.duration.quarterLength = 3.0 @@ -3533,7 +3539,7 @@ def measureNumber(self) -> int|None: default Measure objects have measure number 0. - If an object belongs to multiple measures (not in the same hierarchy...) + If an object belongs to multiple measures (not in the same hierarchy) then it returns the measure number of the :meth:`~music21.base.Music21Object.activeSite` if that is a :class:`~music21.stream.Measure` object. Otherwise, it will use diff --git a/music21/beam.py b/music21/beam.py index 7a86facfd0..3478efc7bf 100644 --- a/music21/beam.py +++ b/music21/beam.py @@ -103,7 +103,7 @@ class BeamException(exceptions21.Music21Exception): duration.typeFromNumDict[64], duration.typeFromNumDict[128], duration.typeFromNumDict[256], duration.typeFromNumDict[512], duration.typeFromNumDict[1024], duration.typeFromNumDict[2048], -) # be sure to add to .fill if extended... +) # be sure to add to .fill if extended class Beam(prebase.ProtoM21Object, EqualSlottedObjectMixin, style.StyleMixin): diff --git a/music21/braille/basic.py b/music21/braille/basic.py index fbc8e377bd..0ff219b696 100644 --- a/music21/braille/basic.py +++ b/music21/braille/basic.py @@ -801,7 +801,7 @@ def noteToBraille( # note duration # ------------- if isinstance(music21Note.duration, duration.GraceDuration): - # TODO: Short Appoggiatura mark... + # TODO: Short Appoggiatura mark nameWithDuration = notesInStep['eighth'] noteTrans.append(nameWithDuration) music21Note.editorial.brailleEnglish.append( @@ -1057,7 +1057,7 @@ def textExpressionToBraille(music21TextExpression, precedeByWordSign=True): f'Text Expression {teWords} {simpleReturn}') return simpleReturn - # not in this basic list... + # not in this basic list allExpr = teWords.split() textExpressionTrans = [] diff --git a/music21/braille/noteGrouping.py b/music21/braille/noteGrouping.py index 0b1e853de9..491f08a327 100644 --- a/music21/braille/noteGrouping.py +++ b/music21/braille/noteGrouping.py @@ -25,7 +25,7 @@ class NoteGroupingTranscriber: ''' - Object that can transcribe note groupings... + Object that can transcribe note groupings. ''' def __init__(self, brailleElementGrouping=None): self.showLeadingOctave = True @@ -33,7 +33,7 @@ def __init__(self, brailleElementGrouping=None): self._upperFirstInFingering = None self._showClefSigns = None - # duplicate of reset... + # duplicate of reset self.previousNote = None self.previousElement = None self.trans = [] @@ -87,7 +87,7 @@ def upperFirstInFingering(self): should the highest be listed first (default True) or last? If not set but self.brailleElementGrouping.upperFirstInNoteFingering - is set, uses that instead. (note the slight difference in names... NoteFingering) + is set, uses that instead. (note the slight difference in names: NoteFingering) >>> ngt = braille.noteGrouping.NoteGroupingTranscriber() >>> ngt.upperFirstInFingering @@ -236,7 +236,7 @@ def optionallyAddDotToPrevious(self, el=None): 1. self.previousElement exists 2. the last character in the current transcription (self.trans) fits the criteria for basic.yieldDots() - 3. one of these three. PreviousElement was...: + 3. one of these three. PreviousElement was: a. a Dynamic. b. a Clef and clef signs are being transcribed c. a TextExpression not ending in "." @@ -261,7 +261,7 @@ def optionallyAddDotToPrevious(self, el=None): # TE is an abbreviation, no extra dot 3 necessary and prev.content[-1] != '.')): for dot in basic.yieldDots(self.trans[-1][0]): - self.trans.insert(-1, dot) # insert one before the end, not append... + self.trans.insert(-1, dot) # insert one before the end, not append prev.editorial.brailleEnglish.append(f'Dot 3 {dot}') return True # only append max one dot. diff --git a/music21/braille/runAllBrailleTests.py b/music21/braille/runAllBrailleTests.py index 98f2b244cc..e0237d9813 100644 --- a/music21/braille/runAllBrailleTests.py +++ b/music21/braille/runAllBrailleTests.py @@ -11,7 +11,7 @@ ''' A Python 3 only module that runs all the braille Tests and no other tests. -Does not run the doctests, unfortunately. TODO: use mainTest somehow... +Does not run the doctests, unfortunately. TODO: use mainTest somehow This module produces a minimum of output which is most helpful to people who are programming music21 on a screen reader. diff --git a/music21/braille/segment.py b/music21/braille/segment.py index 122d25a49b..64dd9f20e5 100644 --- a/music21/braille/segment.py +++ b/music21/braille/segment.py @@ -173,7 +173,7 @@ class BrailleElementGrouping(ProtoM21Object): - These are the defaults, and they are shared across all objects... + These are the defaults, and they are shared across all objects. >>> bg.keySignature @@ -555,7 +555,7 @@ def extractHeading(self): timeSignature = None tempoText = None metronomeMark = None - # find the first keySignature and timeSignature... + # find the first keySignature and timeSignature groupingKeysToProcess = self.groupingKeysToProcess or deque(sorted(self.keys())) @@ -565,7 +565,7 @@ def extractHeading(self): cgk = groupingKeysToProcess.popleft() # cgk = currentGroupingKey cgkAffinityGroup = cgk.affinity - currentBrailleGrouping = self._groupingDict.get(cgk) # currentGrouping... + currentBrailleGrouping = self._groupingDict.get(cgk) # currentGrouping if cgkAffinityGroup == Affinity.SIGNATURE: if len(currentBrailleGrouping) >= 2: @@ -722,7 +722,7 @@ def showLeadingOctaveFromNoteGrouping(self, noteGrouping: BrailleElementGrouping firstNote = allNotes[0] showLeadingOctave = basic.showOctaveWithNote(self.lastNote, firstNote) # noinspection PyAttributeOutsideInit - self.lastNote = allNotes[-1] # probably should not be here... + self.lastNote = allNotes[-1] # probably should not be here return showLeadingOctave @@ -916,7 +916,7 @@ def extractSignatureGrouping(self): def extractTempoTextGrouping(self): ''' - extracts a tempo text and processes it... + Extracts a tempo text and processes it. ''' self.groupingKeysToProcess.appendleft(self.currentGroupingKey) if self.previousGroupingKey.affinity == Affinity.SIGNATURE: @@ -1058,7 +1058,7 @@ def fixOneArticulation(artic, music21NoteStart, allNotes, noteIndexStart): if numSequential < 3: return # else: - # double the articulation on the first note and remove from the next... + # double the articulation on the first note and remove from the next music21NoteStart.articulations.append(artic) for noteIndexContinue in range(noteIndexStart + 1, noteIndexStart + numSequential): @@ -2241,7 +2241,7 @@ def areGroupingsIdentical(noteGroupingA, noteGroupingB): Takes in two note groupings, noteGroupingA and noteGroupingB. Returns True if both groupings have identical contents. False otherwise. - Helper for numRepeats... + Helper for numRepeats. Needs two identical length groupings. diff --git a/music21/braille/text.py b/music21/braille/text.py index 20d2d39ccb..d5720b2b73 100644 --- a/music21/braille/text.py +++ b/music21/braille/text.py @@ -299,7 +299,7 @@ def recenterHeadings(self): Recenter each of the headings so that they exactly align with the text beneath them. - Demonstration with non braille text... + Demonstration with non braille text: >>> heading1 = 'hello' >>> body1 = 'anyoneHome?' + braille.lookup.symbols['space'] + 'yup!' diff --git a/music21/capella/fromCapellaXML.py b/music21/capella/fromCapellaXML.py index 11b5b52c16..75bed08b6d 100644 --- a/music21/capella/fromCapellaXML.py +++ b/music21/capella/fromCapellaXML.py @@ -188,7 +188,7 @@ def partScoreFromSystemScore(self, systemScore: stream.Score) -> stream.Score: partDictById[thisPart.id] = {'part': newPart, 'number': j} else: newPart = partDictById[thisPart.id]['part'] - for el in thisPart: # no need for recurse... + for el in thisPart: # no need for recurse newPart.coreInsert(common.opFrac(el.offset + systemOffset), el) newPart.coreElementsChanged() newScore = stream.Score() @@ -307,7 +307,7 @@ def systemFromSystem(self, systemElement, systemObj=None): raise CapellaImportException( 'No tag found in the tag for the tag for the ' + ' element for this element') - if len(voiceList) == 1: # single voice staff... perfect! + if len(voiceList) == 1: # single voice staff perfect! thisVoiceElement = voiceList[0] noteObjectsList = thisVoiceElement.findall('noteObjects') if not noteObjectsList: @@ -519,7 +519,7 @@ def noteFromHead(self, headElement): noteNameWithOctave = headElement.attrib['pitch'] n = note.Note() n.nameWithOctave = noteNameWithOctave - n.octave = n.octave - 1 # capella octaves are 1 off... + n.octave = n.octave - 1 # capella octaves are 1 off alters = headElement.findall('alter') if len(alters) > 1: diff --git a/music21/chord/__init__.py b/music21/chord/__init__.py index 37f7ad410d..1888cc9768 100644 --- a/music21/chord/__init__.py +++ b/music21/chord/__init__.py @@ -345,7 +345,7 @@ def remove(self, removeItem): Traceback (most recent call last): ValueError: Cannot remove 4 from a chord; try a Pitch or Note object - Like Python's list object does not work on lists... + Like Python's list object, the remove method of chord does not take a list of strings. >>> c = chord.Chord('C4 E4 G4') >>> c.remove(['C4', 'E4']) @@ -416,7 +416,7 @@ def tie(self, value: tie.Tie|None): # d['tie'] = value @property - def volume(self) -> 'music21.volume.Volume': # do NOT change to volume.Volume, see setter... + def volume(self) -> 'music21.volume.Volume': # do NOT change to volume.Volume, see setter ''' Get or set the :class:`~music21.volume.Volume` object for this Chord. @@ -796,7 +796,7 @@ def __getitem__(self, key: int|str|note.Note|pitch.Pitch): >>> c['D-4.style.color'] is None True - Getting by note does not do very much... + Getting by note does not do very much: >>> c[cSharp] @@ -1183,7 +1183,7 @@ def annotateIntervals( >>> c4.annotateIntervals(inPlace=True, stripSpecifiers=False, returnList=True) ['m3', 'P8', 'P5'] - If sortPitches is false it still gives problems... + If sortPitches is false it still gives problems: >>> c4 = chord.Chord(['G4', 'E4', 'B3', 'E3']) >>> c4.annotateIntervals(inPlace=True, stripSpecifiers=False, sortPitches=False) @@ -1520,7 +1520,7 @@ def closedPosition( >>> chord2 - Force octave changes the octave of the bass note (and all notes above it...) + Force octave changes the octave of the bass note (and all notes above it) >>> c2 = chord.Chord(['C#4', 'G5', 'E6']) >>> c2.closedPosition(forceOctave=2) @@ -1530,7 +1530,7 @@ def closedPosition( >>> c3.closedPosition(forceOctave=6) - Redundant pitches are removed by default, but can be retained... + Redundant pitches are removed by default, but can be retained: >>> c4 = chord.Chord(['C#4', 'C5', 'F7', 'F8']) >>> c5 = c4.closedPosition(forceOctave=4, inPlace=False) @@ -1541,7 +1541,7 @@ def closedPosition( >>> c6 - Implicit octaves work fine... + Implicit octaves work fine: >>> c7 = chord.Chord(['A4', 'B4', 'A']) >>> c7.closedPosition(forceOctave=4, inPlace=True) @@ -1549,7 +1549,8 @@ def closedPosition( OMIT_FROM_DOCS - Very specialized fears... + + Very specialized fears: Duplicate octaves were not working @@ -1568,7 +1569,7 @@ def closedPosition( >>> str(c7c.bass()) 'A4' - complex chord for semiclosed-position testing... + Complex chord for semiclosed-position testing: >>> c8 = chord.Chord(['C3', 'E5', 'C#6', 'E-7', 'G8', 'C9', 'E#9']) >>> c8.closedPosition(inPlace=True) @@ -1624,7 +1625,7 @@ def closedPosition( p.octave += 1 if leaveRedundantPitches is not True: - returnObj.removeRedundantPitches(inPlace=True) # here we can always be in place... + returnObj.removeRedundantPitches(inPlace=True) # here we can always be in place # if not inPlace, creates a second new chord object! returnObj.sortAscending(inPlace=True) @@ -1776,9 +1777,9 @@ def rootnessFunction(rootThirdList): return stepNumsToPitches[this_step_num] # FIND ROOT SLOW - # no notes (or more than one...) have perfectlyStackedThirds above them. Return - # the highest scoring note... - # this is the slowest... + # no notes (or more than one) have perfectlyStackedThirds above them. Return + # the highest scoring note + # this is the slowest rootnessFunctionScores = [] orderedChordSteps = (3, 5, 7, 2, 4, 6) @@ -1827,7 +1828,7 @@ def geometricNormalForm(self) -> list[int]: >>> [(pc - normalOrderFirst) % 12 for pc in normalOrder] [0, 4, 7] ''' - # no need to cache, since only DT uses it... + # no need to cache, since only DT uses it # Order pitches pitchClassList = [] for i in range(len(self.pitches)): @@ -1906,7 +1907,7 @@ def getChordStep( Traceback (most recent call last): music21.chord.ChordException: Cannot run getChordStep without a root - (This is in OMIT...) + (This is in OMIT_FROM_etc.) ''' if chordStep >= 8: chordStep -= 7 @@ -2180,7 +2181,8 @@ def getZRelation(self) -> Chord|None: prime = tables.addressToTransposedNormalForm(other) return Chord(prime) return None - # c2.getZRelation() # returns a list in non-ET12 space... + + # c2.getZRelations() # needs a plural form returning a list in non-ET12 space # def hasAnyEnharmonicSpelledPitches(self) -> bool: @@ -2388,7 +2390,7 @@ def inversion( >>> gMajRepeats.inversion(3) Traceback (most recent call last): - music21.chord.ChordException: Could not invert chord...inversion may not exist + music21.chord.ChordException: Could not invert chord: inversion may not exist If testRoot is True then that temporary root is used instead of self.root(). @@ -2493,7 +2495,7 @@ def _setInversion(self, numberOfRunsBeforeCrashing -= 1 if numberOfRunsBeforeCrashing == 0: - raise ChordException('Could not invert chord...inversion may not exist') + raise ChordException('Could not invert chord: inversion may not exist') self.sortAscending(inPlace=True) @@ -2528,7 +2530,7 @@ def _findInversion(self, rootPitch: pitch.Pitch) -> int: else: inv = -1 # no longer raise an exception if not normal inversion - # is this cache worth it? or more trouble than it's worth... + # is this cache worth it? or more trouble than it's worth self._cache['inversion'] = inv return inv @@ -2620,7 +2622,7 @@ def isAugmentedSixth(self, *, permitAnyInversion=False): >>> c.isAugmentedSixth() False - Italian... + Italian: >>> c = chord.Chord(['A-3', 'C4', 'F#4']) >>> c.isAugmentedSixth() @@ -2958,7 +2960,7 @@ def isFrenchAugmentedSixth(self, *, permitAnyInversion=False) -> bool: >>> fr6b.isFrenchAugmentedSixth() False - Inversion matters... + Inversion matters: >>> fr6c = chord.Chord(['C4', 'D4', 'F#4', 'A-4']) >>> fr6c.isFrenchAugmentedSixth() @@ -3003,13 +3005,13 @@ def isGermanAugmentedSixth(self, *, permitAnyInversion=False) -> bool: >>> gr6b.isGermanAugmentedSixth() False - Inversion matters... + Inversion matters: >>> gr6c = chord.Chord(['C4', 'E-4', 'F#4', 'A-4']) >>> gr6c.isGermanAugmentedSixth() False - unless `permitAnyInversion` is True + unless `permitAnyInversion` is True: >>> gr6c.isGermanAugmentedSixth(permitAnyInversion=True) True @@ -3083,7 +3085,7 @@ def isIncompleteMajorTriad(self) -> bool: >>> c2.isIncompleteMajorTriad() False - Remember, MAJOR Triad... + Remember, MAJOR Triad: >>> c3 = chord.Chord(['C4', 'E-3']) >>> c3.isIncompleteMajorTriad() @@ -3228,7 +3230,7 @@ def isItalianAugmentedSixth(self, *, restrictDoublings=False, permitAnyInversion third = self.third fifth = self.fifth - # only the tonic (that is, fifth) can be doubled... + # only the tonic (that is, fifth) can be doubled for p in self.pitches: if p.name == fifth.name: continue @@ -3416,7 +3418,7 @@ def isTranspositionallySymmetrical(self, *, requireIntervallicEvenness=False) -> >>> chord.Chord('C E G#').isTranspositionallySymmetrical() True - ...but not the major triad: + But the major triad is not transpositionally symmetrical: >>> chord.Chord('C E G').isTranspositionallySymmetrical() False @@ -3594,7 +3596,7 @@ def isNinth(self): return bool(self.getChordStep(2)) except ChordException: # pragma: no cover # probably not reachable, since self.third would have caught the same - # exception and returned False... + # exception and returned False return False def isSwissAugmentedSixth(self, *, permitAnyInversion=False): @@ -3827,12 +3829,12 @@ def root(self, >>> cmaj.root() - For some chords we make an exception. For instance, this chord in + For some chords we make an exception. For instance, take this chord in B-flat minor: >>> aDim7no3rd = chord.Chord(['A3', 'E-4', 'G4']) - ...could be considered a type of E-flat 11 chord with a 3rd, but no 5th, + It could be considered a type of E-flat 11 chord with a 3rd, but no 5th, 7th, or 9th, in 5th inversion. That doesn't make sense, so we should call it an A dim 7th chord with no 3rd. @@ -4182,7 +4184,7 @@ def setColor(self, value, pitchTarget=None): >>> c.setColor('red', 'C4') >>> c['0.style.color'] 'red' - >>> c.setColor('blue') # set for whole chord... + >>> c.setColor('blue') # set for whole chord >>> c.style.color 'blue' >>> c['E4.style.color'] @@ -4476,7 +4478,7 @@ def setTie(self, tieObjOrStr: tie.Tie|str, pitchTarget): True Setting a tie with a chord with the same pitch twice requires - getting the exact pitch object out to be sure which one... + getting the exact pitch object out to be sure which one: >>> c2 = chord.Chord(['D4', 'D4']) >>> secondD4 = c2.pitches[1] @@ -5418,7 +5420,7 @@ def normalOrder(self): >>> chord.Chord.formatVectorString(c3.normalOrder) '' - (this is equivalent...) + (this is equivalent:) >>> c3.formatVectorString(c3.normalOrder) '' @@ -5823,7 +5825,7 @@ def quality(self): Note these two edge cases: - >>> chord.Chord('C D E').quality # NB! Major 9th.... + >>> chord.Chord('C D E').quality # NB! Major 9th. 'major' >>> chord.Chord('C E--').quality 'other' diff --git a/music21/clef.py b/music21/clef.py index 00daf53144..29746e3f98 100644 --- a/music21/clef.py +++ b/music21/clef.py @@ -271,12 +271,12 @@ def getStemDirectionForPitches( class PitchClef(Clef): ''' - superclass for all other clef subclasses that use pitches... + Superclass for all other clef subclasses that use pitches. ''' _DOC_ATTR: dict[str, str] = { 'lowestLine': ''' The diatonicNoteNumber of the lowest line of the clef. - (Can be none...) + (Can be `None`) >>> clef.TrebleClef().lowestLine 31 diff --git a/music21/common/decorators.py b/music21/common/decorators.py index 5dd5e05fb1..73f9b7a381 100644 --- a/music21/common/decorators.py +++ b/music21/common/decorators.py @@ -35,7 +35,7 @@ def wrapped_decorator(*arguments, **keywords): klass = arguments[0] arguments = arguments[1:] - # If no arguments were passed... + # If no arguments were passed if len(arguments) == 1 and not keywords and callable(arguments[0]): if is_bound_method: return fn(klass, arguments[0]) @@ -64,8 +64,7 @@ def deprecated(method, startDate=None, removeDate=None, message=None): Use without arguments for a simple case: - - For demonstrating I need to screw with stderr... + For demonstrating I need to screw with stderr: >>> import sys >>> saveStdErr = sys.stderr @@ -75,7 +74,7 @@ def deprecated(method, startDate=None, removeDate=None, message=None): ... def hi(msg): ... print(msg) - (I'm printing "/" at the beginning because message begins with the filename and that is + (I'm printing "/" at the beginning because the message begins with the filepath which is different on each system, but you can't use ellipses at the beginning of a doctest) >>> print('/'); hi('myke') @@ -92,13 +91,13 @@ def deprecated(method, startDate=None, removeDate=None, message=None): Now a new function demonstrating the argument form. - >>> @common.deprecated('February 1972', 'September 2099', 'You should be okay...') + >>> @common.deprecated('February 1972', 'September 2099', 'You should be okay.') ... def bye(msg): ... print(msg) >>> print('/'); bye('world') /...Music21DeprecationWarning: bye was deprecated on February 1972 - and will disappear at or after September 2099. You should be okay... + and will disappear at or after September 2099. You should be okay. ... world diff --git a/music21/common/formats.py b/music21/common/formats.py index a79e2b02ea..8f8dbda1b0 100644 --- a/music21/common/formats.py +++ b/music21/common/formats.py @@ -179,7 +179,7 @@ def findFormat(fmt): @cache def findInputExtension(fmt: str) -> tuple[str, ...]: ''' - Will be fully deprecated when there's an exact equivalent in converter... + Will be fully deprecated when there's an exact equivalent in converter. Given an input format or music21 format, find and return all possible input extensions. @@ -193,7 +193,7 @@ def findInputExtension(fmt: str) -> tuple[str, ...]: >>> common.findInputExtension('musedata') ('.md', '.musedata', '.zip') - Leading dots don't matter... + Leading dots don't matter: >>> common.findInputExtension('.mxl') ('.xml', '.mxl', '.musicxml') diff --git a/music21/common/misc.py b/music21/common/misc.py index 60085615f3..1a7f7b5dce 100644 --- a/music21/common/misc.py +++ b/music21/common/misc.py @@ -10,7 +10,7 @@ # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' -If it doesn't fit anywhere else in the common directory, you'll find it here... +If it doesn't fit anywhere else in the common directory, you'll find it here! ''' from __future__ import annotations @@ -49,13 +49,17 @@ def flattenList(originalList: Iterable[Iterable[_T]]) -> list[_T]: ''' - Flatten a list of lists into a flat list - - but not a list of lists of lists... + Flatten a list of lists into a flat list: >>> l = [[1, 2, 3], [4, 5], [6]] >>> common.flattenList(l) [1, 2, 3, 4, 5, 6] + + But not a list of lists-of-lists! + + >>> l2 = [[1, 2, 3], [4, 5], [6, [7, 8]]] + >>> common.flattenList(l2) + [1, 2, 3, 4, 5, 6, [7, 8]] ''' return [item for sublist in originalList for item in sublist] diff --git a/music21/common/numberTools.py b/music21/common/numberTools.py index 7dd2688b4c..0a708219d4 100644 --- a/music21/common/numberTools.py +++ b/music21/common/numberTools.py @@ -67,7 +67,7 @@ # ----------------------------------------------------------------------------- -# Number methods... +# Number methods def numToIntOrFloat(value: OffsetQLIn) -> int|float: @@ -150,11 +150,11 @@ def _preFracLimitDenominator(n: int, d: int) -> tuple[int, int]: Copied from fractions.limit_denominator. Their method requires creating three new Fraction instances to get one back. - This doesn't create any call before Fraction... + This doesn't create any call before Fraction. - DENOM_LIMIT is hardcoded to defaults.limitOffsetDenominator for speed... + DENOM_LIMIT is hardcoded to defaults.limitOffsetDenominator for speed. - returns a new n, d... + returns a new n, d. >>> common.numberTools._preFracLimitDenominator(100001, 300001) (1, 3) @@ -182,7 +182,7 @@ def _preFracLimitDenominator(n: int, d: int) -> tuple[int, int]: Nothing changed in 2023, in fact, it's faster now with the cache, and even without the cache, it's still 4x faster. - Proof of working... + Proof of working: >>> import random >>> myWay = lambda x: Fraction(*common.numberTools._preFracLimitDenominator( @@ -314,7 +314,7 @@ def opFrac(num: OffsetQLIn) -> OffsetQL: # represented w/ a denominator less than DENOM_LIMIT? # this doesn't work: # (denominator & (denominator-1)) != 0 - # which is a nice test, but denominator here is always a power of two... + # which is a nice test, but denominator here is always a power of two. # unused_numerator, denominator = num.as_integer_ratio() # too slow ir = num.as_integer_ratio() # type: ignore if ir[1] > DENOM_LIMIT: # slightly faster[SIC!] than hard coding 65535! @@ -322,22 +322,22 @@ def opFrac(num: OffsetQLIn) -> OffsetQL: f_out = Fraction(*_preFracLimitDenominator(*ir)) # way faster! # now, reduce denominator as Fraction -- just as below under numType == Fraction d = f_out._denominator # type: ignore - if (d & (d - 1)) == 0: # power of two... + if (d & (d - 1)) == 0: # power of two # 50% faster than float(num) return f_out._numerator / (d + 0.0) # type: ignore else: return f_out # leave non-power of two fractions alone # return Fraction(*ir).limit_denominator(DENOM_LIMIT) # *ir instead of float--can happen - # internally in Fraction constructor, but is twice as fast... + # internally in Fraction constructor, but is twice as fast else: return num elif numType is int: # if vs. elif is negligible time difference. # 8x faster than float(num) return num + 0.0 # type: ignore elif numType is Fraction: - # private access instead of property: 6x faster; may break later... + # private access instead of property: 6x faster; may break later d = num._denominator # type: ignore - if (d & (d - 1)) == 0: # power of two... + if (d & (d - 1)) == 0: # power of two # 50% faster than float(num) return num._numerator / (d + 0.0) # type: ignore else: @@ -345,14 +345,14 @@ def opFrac(num: OffsetQLIn) -> OffsetQL: elif num is None: # undocumented -- used to be documented to return None. callers must check. return 0.0 - # class inheritance only check AFTER "type is" checks... this is redundant but highly optimized. + # class inheritance only check AFTER "type is" checks this is redundant but highly optimized. elif isinstance(num, int): return num + 0.0 elif isinstance(num, float): return opFrac(float(num)) # slower for inherited floats, but simpler than duplicating elif isinstance(num, Fraction): d = num.denominator # Use properties since it is a subclass - if (d & (d - 1)) == 0: # power of two... + if (d & (d - 1)) == 0: # power of two return num.numerator / (d + 0.0) # 50% faster than float(num) else: return num # leave fraction alone diff --git a/music21/common/objects.py b/music21/common/objects.py index 69fd7c7aec..3530e029f0 100644 --- a/music21/common/objects.py +++ b/music21/common/objects.py @@ -227,7 +227,7 @@ def _getSlotsRecursive(self): >>> sorted(list(sSet)) ['_editorial', '_style', 'direction', 'id', 'independentAngle', 'number', 'type'] - When a normal Beam won't cut it... + When a normal Beam won't cut it: >>> class FunkyBeam(beam.Beam): ... __slots__ = ('funkiness', 'groovability') diff --git a/music21/common/stringTools.py b/music21/common/stringTools.py index 25f6d7d1d7..f32c062263 100644 --- a/music21/common/stringTools.py +++ b/music21/common/stringTools.py @@ -200,7 +200,7 @@ def spaceCamelCase(usrStr: str, replaceUnderscore=True, fixMeList=None) -> str: lastIsNum = False post: list[str] = [] - # do not split these... + # do not split these if fixMeList is None: fixupList = ('PMFC',) else: @@ -258,7 +258,7 @@ def getMd5(value=None) -> str: m = hashlib.md5() try: m.update(value) - except TypeError: # unicode... + except TypeError: # unicode m.update(value.encode('UTF-8')) return m.hexdigest() diff --git a/music21/common/weakrefTools.py b/music21/common/weakrefTools.py index 478a5823f4..5a4971bd60 100644 --- a/music21/common/weakrefTools.py +++ b/music21/common/weakrefTools.py @@ -38,7 +38,14 @@ def wrapWeakref(referent: _T) -> weakref.ReferenceType|_T: >>> ref3 = common.wrapWeakref(5) >>> ref3 5 + + OMIT_FROM_DOCS + + Note that the ...Mock was needed after Python 3.13. + When 3.13 is the lowest version, replace ... with the + actual output. ''' + # if isinstance(referent, weakref.ReferenceType): # return referent try: diff --git a/music21/configure.py b/music21/configure.py index 27994b714d..1ce9b4c05d 100644 --- a/music21/configure.py +++ b/music21/configure.py @@ -863,7 +863,7 @@ def _askFillEmptyList(self, default=None, force=None): return False else: # must be True or False if post not in [True, False]: - # this should never happen... + # this should never happen raise DialogException( '_askFillEmptyList(): sub-command returned non True/False value') return post diff --git a/music21/converter/__init__.py b/music21/converter/__init__.py index c51751a27b..821da9f32d 100644 --- a/music21/converter/__init__.py +++ b/music21/converter/__init__.py @@ -123,8 +123,8 @@ class ArchiveManager: >>> data[0:70] '\r None: Generally not necessary to call, since we can just overwrite obsolete pickles, but useful elsewhere. ''' - pickleFp = self.getPickleFp(zipType='gz') # pathlib... + pickleFp = self.getPickleFp(zipType='gz') # pathlib if pickleFp.exists(): os.remove(pickleFp) @@ -401,7 +401,7 @@ def registerSubConverter(newSubConverter: type[subConverters.SubConverter]) -> N ''' Add a SubConverter to the list of registered subConverters. - Example, register a converter for the obsolete Amiga composition software Sonix (so fun...) + Example, register a converter for the obsolete Amiga composition software Sonix (so fun!) >>> class ConverterSonix(converter.subConverters.SubConverter): ... registerFormats = ('sonix',) @@ -631,7 +631,7 @@ def parseFile(self, fp, number=None, try: self._thawedStream = thaw(fpPickle, zipType='zlib') except freezeThaw.FreezeThawException: - environLocal.warn(f'Could not parse pickle, {fpPickle} ...rewriting') + environLocal.warn(f'Could not parse pickle, {fpPickle}. Rewriting') os.remove(fpPickle) self.parseFileNoPickle(fp, number, format, forceSource, **keywords) @@ -644,7 +644,7 @@ def parseFile(self, fp, number=None, environLocal.printDebug('Loading original version') self.parseFileNoPickle(fp, number, format, forceSource, **keywords) if writePickle is True and fpPickle is not None and storePickle is True: - # save the stream to disk... + # save the stream to disk environLocal.printDebug('Freezing Pickle') s = self.stream sf = freezeThaw.StreamFreezer(s, fastButUnsafe=True) @@ -2208,7 +2208,7 @@ def testParseMidiNoQuantize(self): def testIncorrectNotCached(self): ''' Here is a filename with an incorrect extension (.txt for .rnText). Make sure that - it is not cached the second time... + it is not cached the second time. ''' from music21 import harmony diff --git a/music21/converter/subConverters.py b/music21/converter/subConverters.py index 65e87f1101..828bd7373b 100644 --- a/music21/converter/subConverters.py +++ b/music21/converter/subConverters.py @@ -1003,7 +1003,7 @@ def write(self, def show(self, obj, fmt, app=None, subformats=(), **keywords): # pragma: no cover ''' - Override to do something with png... + Override to do something with png ''' returnedFilePath = self.write(obj, fmt, subformats=subformats, **keywords) if 'png' in subformats: diff --git a/music21/corpus/chorales.py b/music21/corpus/chorales.py index 51506b75bc..044a445e36 100644 --- a/music21/corpus/chorales.py +++ b/music21/corpus/chorales.py @@ -1111,11 +1111,11 @@ def __init__(self, self.iterationType = iterationType if numberList is not None: - # TODO: overly complex order of setting... + # TODO: overly complex order of setting self.numberList = numberList if titleList is not None: - # TODO: overly complex order of setting... + # TODO: overly complex order of setting self.titleList = titleList # These assignments must come after .iterationType diff --git a/music21/corpus/corpora.py b/music21/corpus/corpora.py index f66f613c67..10b03635bd 100644 --- a/music21/corpus/corpora.py +++ b/music21/corpus/corpora.py @@ -40,7 +40,7 @@ class Corpus(prebase.ProtoM21Object): __metaclass__ = abc.ABCMeta - # TODO: this is volatile -- should be elsewhere... + # TODO: this is volatile -- should be elsewhere _acceptableExtensions: list[str] = [ 'abc', 'capella', 'midi', 'musicxml', 'musedata', 'humdrum', 'romantext', 'noteworthytext', 'noteworthy' @@ -108,7 +108,7 @@ def _findPaths( matched.append(filename) break - # this is actually twice as slow... + # this is actually twice as slow # for extension in fileExtensions: # for filename in rdp.rglob('*' + extension): # ... etc ... @@ -278,7 +278,7 @@ def getWorkList( >>> coreCorpus = corpus.corpora.CoreCorpus() - This returns 1 even though there is a '.mus' file, which cannot be read... + This returns 1 even though there is a '.mus' file, which cannot be read: >>> len(coreCorpus.getWorkList('cpebach/h186')) 1 @@ -314,7 +314,7 @@ def getWorkList( results.append(path) if results: - # more than one matched...use more stringent criterion: + # more than one matched, so use more stringent criterion: # must have a slash before the name previousResults = results results = [] @@ -983,7 +983,7 @@ def name(self): # class VirtualCorpus(Corpus): # r''' -# A model of the *virtual* corpus. that stays online... +# A model of the *virtual* corpus. that stays online. # # >>> virtualCorpus = corpus.corpora.VirtualCorpus() # diff --git a/music21/corpus/manager.py b/music21/corpus/manager.py index fa23b1266d..d75a05869d 100644 --- a/music21/corpus/manager.py +++ b/music21/corpus/manager.py @@ -95,8 +95,8 @@ def iterateCorpora(returnObjects=True): - We can also get names instead... Note that the name of the main local corpus is 'local' not - None + We can also get names instead. + (Note that the name of the main local corpus is `"local"` not `None`) >>> for i, corpusName in enumerate(corpus.manager.iterateCorpora(returnObjects=False)): ... print(corpusName) @@ -341,7 +341,7 @@ def getMetadataBundleByCorpus(corpusObject: corpora.Corpus) -> bundles.MetadataB >>> mdb1 is cc.metadataBundle True - Non-existent corpus... + Non-existent corpus: >>> lc = corpus.corpora.LocalCorpus('junk') >>> mdb1 = corpus.manager.getMetadataBundleByCorpus(lc) diff --git a/music21/corpus/work.py b/music21/corpus/work.py index b0cfa7a5f0..17e449ff60 100644 --- a/music21/corpus/work.py +++ b/music21/corpus/work.py @@ -46,7 +46,7 @@ def _reprInternal(self): return str(self.directoryName) def findWorks(self): - ''' + r''' Populate other information about the directory such as files and filenames. @@ -65,6 +65,9 @@ def findWorks(self): format='musicxml', ext='.mxl')], virtual=False))]) + + (The ellipses in the documentation above represent '/' on Mac/Unix systems and + '\' on Windows.) ''' self.works.clear() works = self.corpusObject.getComposer(self.directoryName) diff --git a/music21/defaults.py b/music21/defaults.py index 190773e9a6..39f74e7f99 100644 --- a/music21/defaults.py +++ b/music21/defaults.py @@ -82,7 +82,7 @@ # ticks per quarter is used for midi - left separate for flexibility in the future. ticksPerQuarter = divisionsPerQuarter # how many ticks to pad as a rest at the beginning of a MIDI file. -# also used to pad the end..., one quarter note. +# also used to pad the end, one quarter note. ticksAtStart = ticksPerQuarter # quantizationQuarterLengthDivisors @@ -97,7 +97,7 @@ scalingTenths = 40 -jupyterImageDpi = 200 # retina... +jupyterImageDpi = 200 # retina quality (can go higher soon?) # multi-measure rests diff --git a/music21/derivation.py b/music21/derivation.py index 0ca9ba4d33..c27d7e99f0 100644 --- a/music21/derivation.py +++ b/music21/derivation.py @@ -121,7 +121,7 @@ class Derivation(SlottedObjectMixin): Deleting the origin stream does not change the Derivation, since origin is held by strong ref: - >>> import gc # Garbage collection... + >>> import gc # Garbage collection >>> del s2 >>> unused = gc.collect() # ensure Garbage collection is run >>> d1 diff --git a/music21/duration.py b/music21/duration.py index fd9d5361ec..784f684c5a 100644 --- a/music21/duration.py +++ b/music21/duration.py @@ -279,12 +279,12 @@ def quarterLengthToClosestType(qLen: OffsetQLIn) -> tuple[str, bool]: >>> duration.quarterLengthToClosestType(1.8) ('quarter', False) - Some extremely close types will return True for exact conversion... + Some extremely close types will return True for exact conversion: >>> duration.quarterLengthToClosestType(2.0000000000000001) ('half', True) - Very big durations... are fine: + Very long durations are fine: >>> duration.quarterLengthToClosestType(129.99) ('duplex-maxima', False) @@ -303,7 +303,7 @@ def quarterLengthToClosestType(qLen: OffsetQLIn) -> tuple[str, bool]: ''' noteLengthType: OffsetQL if isinstance(qLen, fractions.Fraction): - noteLengthType = 4 / qLen # divides right... + noteLengthType = 4 / qLen # divides right else: noteLengthType = opFrac(4 / qLen) @@ -398,7 +398,7 @@ def quarterLengthToNonPowerOf2Tuplet( power of 2 denominator (such as 7:6) that represents the quarterLength and the DurationTuple that should be used to express the note. - This could be a double-dotted note, but also a tuplet... + This could be a double-dotted note, but also a tuplet: >>> duration.quarterLengthToNonPowerOf2Tuplet(7) (, DurationTuple(type='breve', dots=0, quarterLength=8.0)) @@ -409,7 +409,7 @@ def quarterLengthToNonPowerOf2Tuplet( >>> duration.quarterLengthToNonPowerOf2Tuplet(7/3) (, DurationTuple(type='whole', dots=0, quarterLength=4.0)) - And of course... + And of course: >>> duration.quarterLengthToNonPowerOf2Tuplet(1) (, @@ -519,7 +519,7 @@ def quarterConversion(qLen: OffsetQLIn) -> QuarterLengthConversion: Returns a 2-element namedtuple of (components, tuplet) Components is a tuple of DurationTuples (normally one) that - add up to the qLen when multiplied by... + add up to the qLen when multiplied by the tuplet multiplier. Tuplet is a single :class:`~music21.duration.Tuplet` that adjusts all components. @@ -621,7 +621,7 @@ def quarterConversion(qLen: OffsetQLIn) -> QuarterLengthConversion: Since tuplets apply to the entire Duration (since v2), expect some odder tuplets for unusual - values that should probably be split generally... + values that should probably be split generally: >>> duration.quarterConversion(7/3) QuarterLengthConversion(components=(DurationTuple(type='whole', dots=0, quarterLength=4.0),), @@ -678,9 +678,9 @@ def quarterConversion(qLen: OffsetQLIn) -> QuarterLengthConversion: dt = durationTupleFromTypeDots('zero', 0) return QuarterLengthConversion((dt,), None) - # Tuplets... + # Tuplets qLen = opFrac(qLen) - # try match to type, get next lowest for next part... + # try match to type, get next lowest for next part try: closestSmallerType, unused_match = quarterLengthToClosestType(qLen) nextLargerType(closestSmallerType) @@ -1269,12 +1269,12 @@ def augmentOrDiminish(self, amountToScale: int|float): def setDurationType( self, durType: str|int|float|fractions.Fraction, - dots=0 - ): + dots: int = 0, + ) -> None: ''' Set both durationActual and durationNormal from either a string type or - a quarterLength. optional dots can add dots to a string Type (or I suppose - a quarterLength...but why?) + a quarterLength. optional dots can add dots to a string type (or I suppose + a quarterLength.) >>> a = duration.Tuplet() >>> a.tupletMultiplier() @@ -1309,7 +1309,7 @@ def setDurationType( self.durationActual = durationTupleFromTypeDots(durType, dots) self.durationNormal = durationTupleFromTypeDots(durType, dots) - def setRatio(self, actual, normal): + def setRatio(self, actual: int, normal: int) -> None: ''' Set the ratio of actual divisions to represented in normal divisions. A triplet is 3 actual in the time of 2 normal. @@ -1418,14 +1418,14 @@ def durationActual(self) -> DurationTuple|None: durationActual is a DurationTuple that represents the notes that are actually present and counted in a tuplet. For instance, in a 7 dotted-eighth in the place of 2 double-dotted quarter notes tuplet, - the duration actual would be... + the duration actual would be this: >>> d = duration.Tuplet(7, 2) >>> print(d.durationActual) None >>> d.durationActual = duration.Duration('eighth', dots=1) - Notice that the Duration object gets converted to a DurationTuple + Notice that the Duration object gets converted to a DurationTuple. >>> d.durationActual DurationTuple(type='eighth', dots=1, quarterLength=0.75) @@ -1456,14 +1456,14 @@ def durationNormal(self) -> DurationTuple|None: durationNormal is a DurationTuple that represents the notes that would be present in the space normally (if there were no tuplets). For instance, in a 7 dotted-eighth in the place of 2 double-dotted quarter notes tuplet, - the durationNormal would be... + the durationNormal would be: >>> d = duration.Tuplet(7, 2) >>> print(d.durationNormal) None >>> d.durationNormal = duration.Duration('quarter', dots=2) - Notice that the Duration object gets converted to a DurationTuple + Notice that the Duration object gets converted to a DurationTuple: >>> d.durationNormal DurationTuple(type='quarter', dots=2, quarterLength=1.75) @@ -1808,7 +1808,7 @@ def __deepcopy__(self, memo): if (len(self._components) == 1 and self._dotGroups == (0,) and self._linked is True - and not self._tuplets): # 99% of notes... + and not self._tuplets): # 99% of notes # ignore all but components return self.__class__(durationTuple=self._components[0]) elif (not self._components @@ -2613,7 +2613,7 @@ def dotGroups(self) -> tuple[int, ...]: def dotGroups(self, value: tuple[int, ...]): if not isinstance(value, tuple): raise TypeError('only tuple dotGroups values can be used with this method.') - # removes dots from all components... + # removes dots from all components componentsGenerator = ( durationTupleFromTypeDots(component.type, 0) for component in self._components ) @@ -2680,7 +2680,7 @@ def dots(self) -> int: >>> d.quarterLength 3.998046875 - Infinite dots... (an Easter egg...) + Infinite dots gives an Easter egg: >>> from math import inf >>> d.type = 'half' @@ -2708,7 +2708,7 @@ def dots(self, value: int): if not common.isNum(value): raise TypeError('only numeric dot values can be used with this method.') - # easter egg... + # easter egg if value == inf: self.type = nextLargerType(self.type) self.dots = 0 @@ -3003,7 +3003,7 @@ def aggregateTupletMultiplier(self) -> OffsetQL: This method is needed for MusicXML time-modification among other places. - No tuplets... + No tuplets: >>> complexDur = duration.Duration('eighth') >>> complexDur.aggregateTupletMultiplier() diff --git a/music21/editorial.py b/music21/editorial.py index 62d1ad783c..eeeb75e45c 100644 --- a/music21/editorial.py +++ b/music21/editorial.py @@ -131,6 +131,14 @@ class Comment(prebase.ProtoM21Object, style.StyleMixin): # type: ignore A comment or footnote or something else attached to a note. >>> c = editorial.Comment('presented as C natural in the 1660 print.') + >>> c + + + Note that the text is truncated in representation, but it is all there in `.text`: + + >>> c.text + 'presented as C natural in the 1660 print.' + >>> c.isFootnote = True >>> c.levelInformation = 'musicological' diff --git a/music21/environment.py b/music21/environment.py index 84f9793d2f..dad04e3749 100644 --- a/music21/environment.py +++ b/music21/environment.py @@ -371,7 +371,7 @@ def _loadDefaults(self, forcePlatform=None): # path to a braille viewer self._ref['braillePath'] = None - # path to MuseScore (if not the musicxmlPath...) + # path to MuseScore (if not the musicxmlPath) # for direct creation of PNG from MusicXML self._ref['musescoreDirectPNGPath'] = None self._ref['showFormat'] = 'musicxml' @@ -641,7 +641,7 @@ def getSettingsPath(self): directory = pathlib.Path(os.path.expanduser('~')) return directory / 'music21-settings.xml' elif platform in ['nix', 'darwin']: - # might not exist if running as nobody in a webserver... + # might not exist if running as nobody in a webserver if 'HOME' in os.environ and os.access(os.environ['HOME'], os.W_OK): directory = pathlib.Path(os.environ['HOME']) else: @@ -708,7 +708,7 @@ def formatToKey(self, m21Format): >>> e.formatToKey('braille') 'braillePath' - returns None if there is no key for this format (whether the format exists or not...) + returns None if there is no key for this format (whether the format exists or not) >>> e.formatToKey('ipython') is None # actual format True diff --git a/music21/exceptions21.py b/music21/exceptions21.py index 32c8afb66f..4ad6830808 100644 --- a/music21/exceptions21.py +++ b/music21/exceptions21.py @@ -74,6 +74,6 @@ class TimeSignatureException(MeterException): # warnings class Music21DeprecationWarning(UserWarning): # Do not subclass Deprecation warning, because these - # warnings need to be passed to users... + # warnings need to be passed to users pass diff --git a/music21/expressions.py b/music21/expressions.py index 8fe3a672e7..c56c9782ab 100644 --- a/music21/expressions.py +++ b/music21/expressions.py @@ -119,7 +119,7 @@ def realizeOrnaments( break retList = [] - # TODO: use extend... + # TODO: use extend instead of iteration for i in preExpandList: retList.append(i) if srcObject is not None: diff --git a/music21/features/base.py b/music21/features/base.py index 5b52d0512e..7071c6b46b 100644 --- a/music21/features/base.py +++ b/music21/features/base.py @@ -1157,12 +1157,12 @@ def extractorsById(idOrList, library=('jSymbolic', 'native')): ['P19', 'P20'] - Normalizes case... + Normalizes case: >>> [x.id for x in features.extractorsById(['r31', 'r32', 'r33', 'r34', 'r35', 'p1', 'p2'])] ['R31', 'R32', 'R33', 'R34', 'R35', 'P1', 'P2'] - Get all feature extractors from all libraries + Get all feature extractors from all libraries: >>> y = [x.id for x in features.extractorsById('all')] >>> y[0:3], y[-3:-1] @@ -1495,7 +1495,7 @@ def testEmptyStreamCustomErrors(self): # def testGetAllExtractorsMethods(self): # ''' - # ahh..this test takes a really long time.... + # ahh..this test takes a really long time. # ''' # from music21 import stream, features, pitch # s = corpus.parse('bwv66.6').measures(1, 5) diff --git a/music21/features/jSymbolic.py b/music21/features/jSymbolic.py index 37c666dee2..c2f08d1c48 100644 --- a/music21/features/jSymbolic.py +++ b/music21/features/jSymbolic.py @@ -1493,7 +1493,7 @@ def process(self): ''' Do processing necessary, storing result in feature. ''' - # Create vector with [C, C#, D...] + # Create vector with [C, C#, D, etc.] temp = [0] * self.dimensions for i, count in enumerate(self.data['pitches.pitchClassHistogram']): temp[i] = count @@ -1509,7 +1509,7 @@ class FifthsPitchHistogramFeature(featuresModule.FeatureExtractor): ''' A feature array with bins corresponding to the values of the 5ths pitch class histogram. Instead of the bins being arranged according to semitones -- - [C, C#, D...] -- they are arranged according to the circle of fifths: + [C, C#, D, etc.] -- they are arranged according to the circle of fifths: [C, G, D, A, E, B, F#, C#, G#, D#, A#, F]. Viewing such a histogram may draw attention to the prevalence of a tonal center, including the prevalence of dominant relationships in the piece. diff --git a/music21/figuredBass/realizer.py b/music21/figuredBass/realizer.py index ad606f1338..160fb33333 100644 --- a/music21/figuredBass/realizer.py +++ b/music21/figuredBass/realizer.py @@ -466,7 +466,7 @@ def realize(self, fbRules=None, numParts=4, maxPitch=None): listOfPitchesJustNames = [] for thisPitch in harmonyObject.pitches: listOfPitchesJustNames.append(thisPitch.name) - # remove duplicates just in case... + # remove duplicates just in case d = {} for x in listOfPitchesJustNames: d[x] = x @@ -524,7 +524,7 @@ def _trimAllMovements(self, segmentList): return True elif len(segmentList) >= 3: segmentList.reverse() - # gets this wrong... # pylint: disable=cell-var-from-loop + # gets this wrong # pylint: disable=cell-var-from-loop movementsAB = None for segmentIndex in range(1, len(segmentList) - 1): movementsAB = segmentList[segmentIndex + 1].movements diff --git a/music21/freezeThaw.py b/music21/freezeThaw.py index d1c00dc795..5881f97307 100644 --- a/music21/freezeThaw.py +++ b/music21/freezeThaw.py @@ -267,7 +267,7 @@ def setupSerializationScaffold(self, streamObj=None): streamObj = self.stream if streamObj is None: raise FreezeThawException('You need to pass in a stream when creating to work') - # might not work when recurse yields... + # might not work when recurse yields allEls = list(streamObj.recurse(restoreActiveSites=False)) if self.topLevel is True: @@ -275,7 +275,7 @@ def setupSerializationScaffold(self, streamObj=None): for el in allEls: if isinstance(el, variant.Variant): - # works like a whole new hierarchy... # no need for deepcopy + # works like a whole new hierarchy, so no need for deepcopy subSF = StreamFreezer( el._stream, fastButUnsafe=True, @@ -284,7 +284,7 @@ def setupSerializationScaffold(self, streamObj=None): ) subSF.setupSerializationScaffold() elif isinstance(el, spanner.Spanner): - # works like a whole new hierarchy... # no need for deepcopy + # works like a whole new hierarchy, so no need for deepcopy subSF = StreamFreezer( el.spannerStorage, fastButUnsafe=True, @@ -345,7 +345,7 @@ def recursiveClearSites(self, startObj): >>> sf = freezeThaw.StreamFreezer() - This will remove n from s but leave the rest of the sites intact... + This will remove n from s but leave the rest of the sites intact: >>> sf.setupStoredElementOffsetTuples(s) >>> len(n.sites) @@ -357,13 +357,13 @@ def recursiveClearSites(self, startObj): >>> n.getOffsetBySite(s2) 20.0 - After recursiveClearSites n will be not know its location anywhere... + After recursiveClearSites n will be not know its location anywhere: >>> sf.recursiveClearSites(s) >>> len(n.sites) # just the None site 1 - This leaves n and s2 in strange positions, because n is in s2.elements still.... + This leaves n and s2 in strange positions, because n is in s2.elements still: >>> n in s2.elements True @@ -561,7 +561,7 @@ def findActiveStreamIdsInHierarchy( 4 >>> for streamElement in [s, m, m2, v._stream]: ... if id(streamElement) not in allIds: - ... print('this should not happen...', allIds, id(streamElement)) + ... print('this should not happen!', allIds, id(streamElement)) N.B. with variants: @@ -590,8 +590,8 @@ def findActiveStreamIdsInHierarchy( for el in streamObj.recurse(includeSelf=True).getElementsByClass(variant.Variant): streamIds += self.findActiveStreamIdsInHierarchy(el._stream) - # should not happen that there are duplicates, but possible with spanners... - # Python's uniq value... + # should not happen that there are duplicates, but possible with spanners + # Python's uniq value streamIds = list(set(streamIds)) self.streamIds = streamIds @@ -637,7 +637,7 @@ def write(self, fmt='pickle', fp=None, zipType=None, **keywords): No other compression types are currently supported. ''' if zipType not in (None, 'zlib'): # pragma: no cover - raise FreezeThawException('Cannot zip files except zlib...') + raise FreezeThawException('Cannot zip files except zlib type') fmt = self.parseWriteFmt(fmt) @@ -775,7 +775,7 @@ def teardownSerializationScaffold(self, streamObj=None): for e in allEls: eClasses = e.classes if 'Variant' in eClasses: - # works like a whole new hierarchy... # no need for deepcopy + # works like a whole new hierarchy, so no need for deepcopy subSF = StreamThawer() subSF.teardownSerializationScaffold(e._stream) e._cache = {} @@ -847,7 +847,7 @@ def restoreElementsFromTuples(self, streamObj): try: streamObj.coreInsert(offset, e) except AttributeError: # pragma: no cover - print('Problem in decoding... some debug info...') + print('Problem in decoding. Here is some debug info:') print(offset, e) print(streamObj) print(streamObj.activeSite) @@ -868,7 +868,7 @@ def restoreStreamStatusClient(self, streamObj): ''' Restore the streamStatus client to point to the Stream (do we do this for derivations? No: there should not be derivations stored. - Other objects? Unclear...) + Other objects? Unclear at present.) ''' if hasattr(streamObj, 'streamStatus'): streamObj.streamStatus.client = streamObj @@ -1014,7 +1014,7 @@ def testFreezeThawWithSpanner(self): self.assertIs(s.spanners[0].getFirst(), s.notes[0]) sf = StreamFreezer(s) - out = sf.writeStr(fmt='jsonpickle') # easier to read... + out = sf.writeStr(fmt='jsonpickle') # easier to read del s del sDummy diff --git a/music21/graph/__init__.py b/music21/graph/__init__.py index 4e6877c5dc..4b8bfeee9a 100644 --- a/music21/graph/__init__.py +++ b/music21/graph/__init__.py @@ -152,7 +152,7 @@ def plotStream( setattr(obj, attrName, axisClass(obj, axisName)) obj.run() - return obj # just last one... + return obj # just last one # ------------------------------------------------------------------------------ class TestExternal(unittest.TestCase): diff --git a/music21/graph/axis.py b/music21/graph/axis.py index b81972211b..2d81965d28 100644 --- a/music21/graph/axis.py +++ b/music21/graph/axis.py @@ -182,7 +182,7 @@ def stream(self): def extractOneElement(self, n, formatDict): ''' - Override in subclasses... + Override in subclasses ''' return 1 @@ -407,7 +407,7 @@ def unweightedSortHelper(x): label = None if not weights: # get a default if self.hideUnused: - continue # don't append any ticks... + continue # don't append any ticks if not self.blankLabelUnused: label = getattr(p, attributeCounter) else: # use an empty label to maintain spacing @@ -524,7 +524,7 @@ def ticks(self): 10 Bâ™­ 11 B - .showEnharmonic will change here... + `.showEnharmonic` will change here: >>> s.append(note.Note('A#4')) >>> s.append(note.Note('G#4')) @@ -567,7 +567,7 @@ def ticks(self): OMIT_FROM_DOCS TODO: this ultimately needs to look at key signature/key to determine - defaults for undefined notes where blankLabelUnused is False... + defaults for undefined notes where blankLabelUnused is False. ''' # keys are integers # name strings are keys, and enharmonic are thus different @@ -576,7 +576,7 @@ def ticks(self): class PitchSpaceAxis(PitchAxis): ''' - Axis subclass for dealing with PitchSpace (MIDI numbers...) + Axis subclass for dealing with PitchSpace (MIDI numbers) ''' labelDefault = 'Pitch' quantities: tuple[str, ...] = ('pitchSpace', 'pitch', 'pitchspace', 'ps') @@ -787,7 +787,7 @@ class OffsetAxis(PositionAxis): def __init__(self, client=None, axisName='x'): super().__init__(client, axisName) self.useMeasures = None - # self.displayMeasureNumberZero = False # not used... + # self.displayMeasureNumberZero = False # not used self.offsetStepSize = 10 self.mostMeasureTicksToShow = 20 self.minMaxMeasureOnly = False diff --git a/music21/graph/findPlot.py b/music21/graph/findPlot.py index 8b5c5673d9..bf31b67ced 100644 --- a/music21/graph/findPlot.py +++ b/music21/graph/findPlot.py @@ -50,7 +50,7 @@ def getPlotClasses() -> list[type[plot.PlotStreamMixin]]: ''' - return a list of all PlotStreamMixin subclasses... returns sorted list by name + return a list of all PlotStreamMixin subclasses. Returns a list sorted by name >>> graph.findPlot.getPlotClasses() [, @@ -75,7 +75,7 @@ def getPlotClasses() -> list[type[plot.PlotStreamMixin]]: def getAxisClasses() -> list[type[axis.Axis]]: ''' - return a list of all Axis subclasses... returns sorted list by name + return a list of all Axis subclasses. Returns a list sorted by name >>> graph.findPlot.getAxisClasses() [, @@ -278,7 +278,7 @@ def getPlotsToMake(graphFormat: str|None = None, [, ] - Just one value, but it is in the wrong axis... + Just one value, but it is in the wrong axis: >>> graph.findPlot.getPlotsToMake('scatter', 'pitchClass') [, @@ -315,7 +315,7 @@ def getPlotsToMake(graphFormat: str|None = None, ''' def _bestPlotType(graphClassesToChooseFrom): - # now get the best graph type from this possibly motley list... + # now get the best graph type from this possibly motley list numAxes = len([1 for val in (xValue, yValue, zValue) if val is not None]) bestGraphType = '' @@ -344,8 +344,8 @@ def _bestPlotType(graphClassesToChooseFrom): if not graphClasses and graphFormat: xValue, yValue, zValue = graphFormat, xValue, yValue graphFormat = None - graphClasses = getPlotClasses() # assume graphFormat is an axis and shift over... - # match values to axes... + graphClasses = getPlotClasses() # assume graphFormat is an axis and shift over + # match values to axes graphRemove = [] for axisLetter, axisValue in (('x', xValue), ('y', yValue), ('z', zValue)): @@ -366,7 +366,7 @@ def _bestPlotType(graphClassesToChooseFrom): else: return _bestPlotType(graphClassesFiltered) - # no matches for values. Try agnostic about X and Y... + # no matches for values. Try agnostic about X and Y graphRemove = [] for axisLetter, axisValue in (('x', xValue), ('y', yValue), ('z', zValue)): for gc in graphClasses: @@ -388,7 +388,7 @@ def _bestPlotType(graphClassesToChooseFrom): else: return _bestPlotType(graphClassesFiltered) - # if still not found, return a dict with the proper axes... + # if still not found, return a dict with the proper axes axisDict = collections.OrderedDict() for axisLetter, axisValue in (('x', xValue), ('y', yValue), ('z', zValue)): @@ -406,7 +406,7 @@ def _bestPlotType(graphClassesToChooseFrom): if filteredClasses: return [(filteredClasses[0], axisDict)] - else: # we have done our best... + else: # we have done our best return [(graphClasses[0], axisDict)] diff --git a/music21/graph/plot.py b/music21/graph/plot.py index 1fd1fbd41e..b1cf52b20a 100644 --- a/music21/graph/plot.py +++ b/music21/graph/plot.py @@ -236,7 +236,7 @@ def processOneElement(self, el: base.Music21Object): ''' elementValues: list[list[t.Any]] = [[] for _ in range(len(self.allAxes))] formatDict: dict[t.Any, t.Any] = {} - # should be two for most things... + # should be two for most things if not isinstance(el, chord.Chord): for i, thisAxis in enumerate(self.allAxes): @@ -896,7 +896,7 @@ def processor(self): def run(self, *, callProcess: bool = True, **keywords): ''' - actually create the graph... + Actually creates the graph. ''' if self.title == 'Music21 Graph' and self.processor: self.title = (self.processor.name @@ -1437,7 +1437,7 @@ class MultiStream(primitives.GraphGroupedVerticalBar, PlotStreamMixin): Approaches to plotting and graphing multiple Streams. A base class from which Stream plotting Classes inherit. - Not yet integrated into the new 2017 system, unfortunately... + Not yet integrated into the 2017 system, unfortunately. Provide a list of Streams as an argument. Optionally provide an additional list of labels for each list. diff --git a/music21/graph/primitives.py b/music21/graph/primitives.py index 4956b489f6..4e89bc9200 100644 --- a/music21/graph/primitives.py +++ b/music21/graph/primitives.py @@ -221,7 +221,7 @@ def doneAction(self, action): def nextColor(self): ''' - Utility function that cycles through the colors of self.colors... + Utility function that cycles through the colors of self.colors. >>> g = graph.primitives.Graph() >>> g.colors = ['#605c7f', '#5c7f60', '#715c7f'] @@ -250,7 +250,7 @@ def setTicks(self, axisKey, pairs): Pairs are iterables of positions and labels. N.B. -- both 'x' and 'y' ticks have to be set in - order to get matplotlib to display either... (and presumably 'z' for 3D graphs) + order to get matplotlib to display either (and presumably 'z' for 3D graphs). >>> g = graph.primitives.GraphHorizontalBar() >>> g.axis['x']['ticks'] @@ -271,7 +271,7 @@ def setTicks(self, axisKey, pairs): >>> g.axis['x']['ticks'] ([], []) ''' - if pairs is None: # is okay to send an empty list to clear everything... + if pairs is None: # is okay to send an empty list to clear everything return if axisKey not in self.axis: diff --git a/music21/graph/utilities.py b/music21/graph/utilities.py index 6abb3ef719..8737e88a24 100644 --- a/music21/graph/utilities.py +++ b/music21/graph/utilities.py @@ -90,7 +90,7 @@ def accidentalLabelToUnicode(label): 'Bâ™­4' Since matplotlib's default fonts do not support double sharps or double flats, - etc. these are converted as best we can... + etc. these are converted as best we can. >>> graph.utilities.accidentalLabelToUnicode('B--4') 'Bâ™­â™­4' @@ -99,7 +99,7 @@ def accidentalLabelToUnicode(label): return label for modifier, unicodeAcc in pitch.unicodeFromModifier.items(): if modifier != '' and modifier in label and modifier in ('-', '#'): - # ideally eventually matplotlib will do the other accidentals... + # ideally eventually matplotlib will do the other accidentals label = label.replace(modifier, unicodeAcc) break diff --git a/music21/harmony.py b/music21/harmony.py index 925f0fe087..cb81127385 100644 --- a/music21/harmony.py +++ b/music21/harmony.py @@ -226,7 +226,7 @@ def __init__(self, # data inconsistency. # a romanNumeral numeral object, musicxml stores this within a node - # called which might conflict with the Harmony... + # called which might conflict with the Harmony self._roman = None # specify an array of degree alteration objects self.chordStepModifications: list[ChordStepModification] = [] @@ -952,7 +952,8 @@ def chordSymbolFigureFromChord(inChord: chord.Chord, includeChordType=False): ('E-o11', 'diminished-11th') THIRTEENTHS - these are so tricky...music21 needs to be told what the root is in these cases + + These are so tricky: music21 needs to be told what the root is in these cases all tests here are 'C' chords, but any root will work: >>> c = chord.Chord(['C3', 'E3', 'G3', 'B3', 'D4', 'F4', 'A4']) @@ -1000,8 +1001,7 @@ def chordSymbolFigureFromChord(inChord: chord.Chord, includeChordType=False): * eleventh chords: third and/or fifth * thirteenth chords: fifth, eleventh, ninth - - This Chord could be minor 7th with a C4, but because this 5th isn't present, not identified + This chord could be minor 7th with a C4, but because this 5th is not present, it is not identified >>> c = chord.Chord(['F3', 'A-3', 'E-4']) >>> harmony.chordSymbolFigureFromChord(c) @@ -1334,7 +1334,7 @@ def convertFBNotationStringToDegrees(innerKind, fbNotation): perfect = {p.name for p in ChordSymbol(cs).pitches} inPitches = {p.name for p in inChord.pitches} - if not perfect.issuperset(inPitches): # must be subtraction or deletion.... + if not perfect.issuperset(inPitches): # must be subtraction or deletion. additions = inPitches.difference(perfect) subtractions = perfect.difference(inPitches) if additions: @@ -1527,10 +1527,8 @@ class ChordSymbol(Harmony): >>> [str(p) for p in harmony.ChordSymbol('C35911').pitches] ['C2', 'E2', 'G2', 'D3', 'F3'] - to prevent ambiguity in notation... - - ...and in accordance with the rest of music21, if a root or bass is flat, - the '-' must be used, and NOT 'b'. However, alterations and chord + to prevent ambiguity in notation and in accordance with the rest of music21, + if a root or bass is flat, the '-' must be used, and NOT 'b'. However, alterations and chord abbreviations are specified normally with the 'b' and '#' signs. >>> dFlat = harmony.ChordSymbol('D-35') @@ -1633,7 +1631,7 @@ def _adjustOctaves(self, pitches): if not isinstance(pitches, list): pitches = list(pitches) - # do this for all ninth, thirteenth, and eleventh chords... + # do this for all ninth, thirteenth, and eleventh chords # this must be done to get octave spacing right # possibly rewrite figured bass function with this integrated? ninths = ['dominant-ninth', 'major-ninth', 'minor-ninth'] @@ -1749,7 +1747,7 @@ def typeAdd(hD): # if hD.degree == 7 and self.chordKind is not None and self.chordKind != '': # # don't know why anyone would want # # to add a seventh to a dominant chord already - # # ...but according to documentation + # # however, according to documentation # # added degrees are relative to dominant chords, which have all major degrees # # except for the seventh which is minor, thus the transposition down # # one half step @@ -1814,7 +1812,7 @@ def typeAlter(hD): # if str(hD.degree) in degreeString: # self._degreesList = self._degreesList.replace( # degreeString, ('A' + str(hD.degree))) - # # the 'A' stands for altered... + # # the 'A' stands for altered # break # # if hD.degree not in string: # # should we throw an exception???? for now yes, but maybe later we should. @@ -1822,7 +1820,7 @@ def typeAlter(hD): raise ChordStepModificationException( f'Degree not in specified chord: {hD.degree}') - # main routines... + # main routines for chordStepModification in chordStepModifications: if chordStepModification.modType == 'add': typeAdd(chordStepModification) @@ -1946,7 +1944,7 @@ def _parseFigure(self) -> None: ''' if self.figure == 'Chord Symbol Cannot Be Identified': return - # remove spaces from prelim Figure... + # remove spaces from prelim Figure prelimFigure = self.figure prelimFigure = re.sub(r'\s', '', prelimFigure) # Get Root: @@ -3251,7 +3249,7 @@ def testChordRealization(self): # There is a test file under demos called ComprehensiveChordSymbolsTestFile.xml # that should contain a complete iteration of tests of chord symbol objects # this test makes sure that no error exists, and checks that 57 chords were - # created out of that file....feel free to add to file if you find missing + # created out of that file. Feel free to add to file if you find missing # tests, and adjust 57 accordingly testFile = corpus.parse('demos/ComprehensiveChordSymbolsTestFile.xml') diff --git a/music21/humdrum/__init__.py b/music21/humdrum/__init__.py index 30465e325f..2ebdd1eeba 100644 --- a/music21/humdrum/__init__.py +++ b/music21/humdrum/__init__.py @@ -49,7 +49,7 @@ melac_ see Notes :meth:`~music21.analysis.metrical.thomassenMelodicAccent`. incorporates humdrum additions for giving accent of the first and last notes. metpos_ `1 / obj.beatStrength()` the beatStrength of an object is essentially something similar but inverted. beatStrength handles irregular meters. midi_ `.show('midi')` -midireset_ None Not needed for now because we do not write directly to MIDI. A midi.allOff() will be needed for direct midi access... +midireset_ None Not needed for now because we do not write directly to MIDI. A midi.allOff() will be needed for direct midi access. mint_ `interval.Interval(note1, note2)` Or :meth:`~music21.stream.Stream.melodicIntervals` nf_ :meth:`~music21.chord.Chord.normalOrder` Also :meth:`~music21.chord.Chord.primeForm`, :meth:`~music21.chord.Chord.intervalVector`, :meth:`~music21.chord.Chord.forteClass`, :meth:`~music21.chord.Chord.getZRelation` etc. num_ Not needed try: `for i in range(len(s.recurse().getElementsByClass(X)))` etc. diff --git a/music21/humdrum/questions.py b/music21/humdrum/questions.py index 6ee49c41ea..eea0921ece 100644 --- a/music21/humdrum/questions.py +++ b/music21/humdrum/questions.py @@ -18,7 +18,7 @@ class Test(unittest.TestCase): def xtest001(self): pass - # thoughts on how to do this... + # thoughts on how to do this? # def xtest001(self): # ''' # Above G4 do higher pitches tend to be louder? @@ -30,7 +30,7 @@ def xtest001(self): # # partStream = converter.parse('dichterliebe1.xml') # - # ## make monophonic or make chords have a single pitch object... + # ## make monophonic or make chords have a single pitch object # notesAbove, notesBelow = analysis.partition(partStream, 'pitch', 'G4') # # notesAbove, notesBelow = analysis.partition(partStream, # # this.pitch.midiNote > G4.midiNote) @@ -169,7 +169,7 @@ def xtest004(self): # chordSequenceMatch = chord.factory('V64'), chord.factory('I') # # partStream = music21.converter.parse('dichterliebe1.xml') - # ## when we have a passing-tone etc. removal program run here... + # ## when we have a passing-tone etc. removal program run here # # chordStream = analysis.phraseExtract(partStream, ['simultaneities']) # @@ -189,7 +189,7 @@ def xtest004(self): # # are active, not just present # # keys thus do not need a duration # - # ### getElementsByOffsetRange.... + # ### getElementsByOffsetRange. # key = keyStream.getElementsByOffset(chordThis.offset, # chordNext.offset, lastActive=True) # if (chordThis.setKey(key) == chordSequenceMatch[0](key) and diff --git a/music21/humdrum/spineParser.py b/music21/humdrum/spineParser.py index b2b1bc9258..c51f958fdd 100644 --- a/music21/humdrum/spineParser.py +++ b/music21/humdrum/spineParser.py @@ -653,7 +653,7 @@ def createHumdrumSpines(self, protoSpines=None, eventCollections=None): # or merge back to other spine's parent: elif mergerActive is not True: # other spine parent set newSpineList.append(mergerActive) - # or make a new spine... + # or make a new spine: else: s = spineCollection.addSpine(streamClass=stream.Part) s.insertPoint = i @@ -707,7 +707,7 @@ def insertGlobalEvents(self): for j in range(i + 1, maxEventList): if j in positionDict: insertOffset = positionDict[j][0] - # hopefully not more than 20 events in a row... + # hopefully not more than 20 events in a row! insertPriority = (positionDict[j][1][0].priority - 40 + numberOfGlobalEventsInARow) @@ -749,11 +749,11 @@ def insertGlobalEvents(self): # if self.spineCollection is None: # raise HumdrumException('parsing got no spine collections!') # elif self.spineCollection.spines is None: - # raise HumdrumException('not a single spine in your data... um, not my problem! ' + - # '(well, maybe it is...file a bug report if you ' + + # raise HumdrumException('not a single spine in your data. Is this your problem? ' + + # '(File a bug report if you ' + # 'have doubled checked your data)') # elif self.spineCollection.spines[0].stream is None: - # raise HumdrumException('okay, you got at least one spine, but it ain\'t got ' + + # raise HumdrumException('okay, you got at least one spine, but it does not have ' + # 'a stream in it; (check your data or file a bug report)') # else: # masterStream = stream.Score() @@ -991,7 +991,7 @@ def __init__(self, eventList=None): # HUMDRUM SPINES # -# Ready to be parsed... +# Ready to be parsed. class HumdrumSpine(prebase.ProtoM21Object): r''' A HumdrumSpine is a representation of a generic HumdrumSpine @@ -1161,7 +1161,7 @@ def moveElementsIntoMeasures(self, streamIn): ''' Takes a parsed stream and moves the elements inside the measures. Works with pickup measures, etc. Does not - automatically create ties, etc... + automatically create ties, etc. Why not just use Stream.makeMeasures()? because humdrum measures contain extra information about barlines @@ -1230,7 +1230,7 @@ def moveElementsIntoMeasures(self, streamIn): if currentMeasure: streamOut.append(currentMeasure) - # move beginning stuff (Clefs, KeySig, etc.) to first measure... + # move beginning stuff (Clefs, KeySig, etc.) to first measure. measureElements = streamOut.getElementsByClass(stream.Measure) if measureElements: m1 = measureElements[0] @@ -1345,10 +1345,10 @@ def parse(self): ) tb = traceback.format_exc() environLocal.printDebug(f'Traceback for the exception: \n{tb}') - # traceback... environLocal.printDebug() + # traceback: environLocal.printDebug() self.stream.coreElementsChanged() - # still to be done later... move things before first measure to first measure! + # still to be done later. Move things before first measure to first measure! def processNoteEvent(self, eventC): ''' @@ -1406,7 +1406,7 @@ def setBeamsForNote(self, n): self.currentBeamNumbers += 1 def setTupletTypeForNote(self, n): - # nested tuplets not supported by humdrum... + # nested tuplets not supported by humdrum. nDur = n.duration nTuplets = n.duration.tuplets @@ -1951,7 +1951,7 @@ def moveDynamicsAndLyricsToStreams(self): el.activeSite.insert(el.offset, prioritiesToSearch[el.priority]) except exceptions21.StreamException: - # may appear twice because of voices... + # may appear twice because of voices pass # el.activeSite.insert(el.offset, # copy.deepcopy(prioritiesToSearch[el.priority])) @@ -1968,7 +1968,7 @@ def moveDynamicsAndLyricsToStreams(self): el.activeSite.insert(el.offset, prioritiesToSearch[el.priority]) except exceptions21.StreamException: - # may appear twice because of voices... + # may appear twice because of voices pass # el.activeSite.insert(el.offset, # copy.deepcopy(prioritiesToSearch[el.priority])) @@ -2316,7 +2316,7 @@ def hdStringToNote(contents): # 3.2.7 Duration + # 3.2.8 N-Tuplets - # TODO: SPEEDUP -- only search for rational after foundNumber... + # TODO: SPEEDUP -- only search for rational after foundNumber. foundRational = re.search(r'(\d+)%(\d+)', contents) foundNumber = re.search(r'(\d+)', contents) if foundRational: @@ -2359,7 +2359,7 @@ def hdStringToNote(contents): # The Josquin Research Project uses an incorrect definition of # humdrum tuplets that breaks normal usage. TODO: Refactor adding a Flavor = 'JRP' - # code that uses this other method... + # code that uses this other method. JRP = flavors['JRP'] if JRP is False and '.' in contents: newTup.durationNormal = duration.durationTupleFromTypeDots( @@ -2515,15 +2515,15 @@ def kernTandemToObject(tandem): return clef.PercussionClef() elif clefType == 'Gv2': # undocumented in Humdrum, but appears in Huron's Chorales return clef.Treble8vbClef() - elif clefType == 'Gv': # unknown if ever used but better safe... + elif clefType == 'Gv': # unknown if ever used but better safe. return clef.Treble8vbClef() - elif clefType == 'G^2': # unknown if ever used but better safe... + elif clefType == 'G^2': # unknown if ever used but better safe. return clef.Treble8vaClef() - elif clefType == 'G^': # unknown if ever used but better safe... + elif clefType == 'G^': # unknown if ever used but better safe. return clef.Treble8vaClef() - elif clefType == 'Fv4': # unknown if ever used but better safe... + elif clefType == 'Fv4': # unknown if ever used but better safe. return clef.Bass8vbClef() - elif clefType == 'Fv': # unknown if ever used but better safe... + elif clefType == 'Fv': # unknown if ever used but better safe. return clef.Bass8vbClef() else: try: @@ -2764,7 +2764,7 @@ def __init__(self, codeOrAll='', valueOrNone=None, **keywords): 'OPR': 'parentTitle', # title of parent work 'OAC': 'actNumber', # act number (e.g. '2' or 'Act 2') 'OSC': 'sceneNumber', # scene number (e.g. '3' or 'Scene 3') - 'OMV': 'movementNumber', # movement number (e.g. '4', or 'mov. 4', or...) + 'OMV': 'movementNumber', # movement number (e.g. '4', or 'mov. 4') 'OMD': 'movementName', # movement name 'OPS': 'opusNumber', # opus number (e.g. '23', or 'Opus 23') 'ONM': 'number', # number (e.g. number of song within ABC multi-song file) @@ -2951,7 +2951,7 @@ def testSpineMazurka(self): # masterStream.show('text') for n in masterStream.recurse(): if hasattr(n, 'pitch') and n.pitch.name == 'G#': - if n.beat == 2: # beat doesn't work... :-( + if n.beat == 2: # beat doesn't work :-( gSharpCount += 1 elif hasattr(n, 'pitches'): for p in n.pitches: diff --git a/music21/instrument.py b/music21/instrument.py index ecefc2216c..4cecfe77ec 100644 --- a/music21/instrument.py +++ b/music21/instrument.py @@ -178,7 +178,7 @@ def __init__(self, instrumentName: str|None = None, **keywords): self.transposition: interval.Interval|None = None self.inGMPercMap = False - self.soundfontFn = None # if defined... + self.soundfontFn = None # if defined def __str__(self): msg = [] @@ -1138,7 +1138,7 @@ def _setModifier(self, modifier): if self.inGMPercMap is True and modifier.lower() in self._modifierToPercMapPitch: self.percMapPitch = self._modifierToPercMapPitch[modifier.lower()] - # normalize modifiers... + # normalize modifiers if self.percMapPitch in self._percMapPitchToModifier: modifier = self._percMapPitchToModifier[self.percMapPitch] @@ -2112,7 +2112,7 @@ def partitionByInstrument(streamObj: stream.Stream) -> stream.Stream: >>> p1.getElementsByClass(stream.Measure)[1].insert(3.0, instrument.Piccolo()) >>> p2.getElementsByClass(stream.Measure)[0].insert(0.0, instrument.Trombone()) - >>> p2.getElementsByClass(stream.Measure)[0].insert(3.0, instrument.Piccolo()) # not likely... + >>> p2.getElementsByClass(stream.Measure)[0].insert(3.0, instrument.Piccolo()) # not likely >>> p2.getElementsByClass(stream.Measure)[1].insert(1.0, instrument.Trombone()) >>> s = stream.Score() @@ -2162,11 +2162,12 @@ def partitionByInstrument(streamObj: stream.Stream) -> stream.Stream: >>> len(s2.parts) 3 - # TODO: this step might not be necessary... + # TODO: this step might not be necessary: + >>> for p in s2.parts: ... p.makeRests(fillGaps=True, inPlace=True) - # TODO: this step SHOULD not be necessary (.template())... + # TODO: this step SHOULD not be necessary (.template()): >>> for p in s2.parts: ... p.makeMeasures(inPlace=True) @@ -2295,7 +2296,7 @@ def partitionByInstrument(streamObj: stream.Stream) -> stream.Stream: pass # it is possible to enter an element twice because the getElementsByOffset # might return something twice if it's at the same offset as the - # instrument switch... + # instrument switch for inst in post.recurse().getElementsByClass(Instrument): inst.duration.quarterLength = 0 diff --git a/music21/interval.py b/music21/interval.py index 1d9fe2863c..acaeef5b2d 100644 --- a/music21/interval.py +++ b/music21/interval.py @@ -441,7 +441,7 @@ def parseSpecifier(value: str|int|Specifier) -> Specifier: >>> interval.parseSpecifier(3) - Why? because... + Why? Because of this: >>> interval.Specifier.MINOR.value 3 @@ -512,7 +512,7 @@ def convertGeneric(value: int|str) -> int: Traceback (most recent call last): music21.interval.IntervalException: Cannot get a direction from None. - Strings are not the same as numbers... + Strings are not the same as numbers: >>> interval.convertGeneric('1') Traceback (most recent call last): @@ -1440,7 +1440,7 @@ def transposePitchKeyAware( But if a key or keySignature (such as one from `.getContextByClass(key.KeySignature)`) - is given, then the fun begins... + is given, then the fun begins: >>> fis = pitch.Pitch('F#4') >>> e = pitch.Pitch('E') @@ -1726,7 +1726,7 @@ def __eq__(self, other): elif not hasattr(other, 'specifier'): return False - # untested... + # untested # if self.direction != other.direction: # return False if (self.generic == other.generic @@ -2658,7 +2658,7 @@ def _getSpecifierFromGenericChromatic( ''' Given a :class:`~music21.interval.GenericInterval` and a :class:`~music21.interval.ChromaticInterval` object, return a specifier - (i.e. Specifier.MAJOR, Specifier.MINOR, etc...). + (i.e. Specifier.MAJOR, Specifier.MINOR, etc.). >>> aInterval = interval.GenericInterval('seventh') >>> bInterval = interval.ChromaticInterval(11) @@ -2690,7 +2690,7 @@ def _getSpecifierFromGenericChromatic( # all normal intervals theseSemis = cInt.undirected # round out microtones - # fix python3 rounding... + # fix python3 rounding if cInt.undirected > 0: roundingError = 0.0001 else: @@ -2984,7 +2984,7 @@ class Interval(IntervalBase): >>> aInterval.isStep True - This is in OMIT... put changelog above. + This is in OMIT_FROM_etc. put changelog above. ''' def __init__(self, arg0: t.Union[str, @@ -3515,7 +3515,7 @@ def _diatonicTransposePitch(self, pitch2.accidental.displayStatus = False else: - # no halfStepsToFix, so pitch2 is fine as is, but... + # no halfStepsToFix, so pitch2 is fine as is, but if inheritAccidentalDisplayStatus: # We have set pitch2.accidental to None, so we might have lost some # display options. So we restore oldPitch2Accidental if that makes sense. @@ -3932,7 +3932,7 @@ def add(intervalList): Add a list of intervals and return the composite interval Intervals can be Interval objects or just strings. - (Currently not particularly efficient for large lists...) + (Currently not particularly efficient for large lists) >>> A2 = interval.Interval('A2') >>> P5 = interval.Interval('P5') @@ -3953,7 +3953,7 @@ def add(intervalList): if not intervalList: raise IntervalException('Cannot add an empty set of intervals') - p1 = pitch.Pitch('C4') # need octave to not be implicit... + p1 = pitch.Pitch('C4') # need octave to not be implicit p2 = pitch.Pitch('C4') for i in intervalList: p2 = transposePitch(p2, i) diff --git a/music21/key.py b/music21/key.py index b8c612ff04..5085835c4d 100644 --- a/music21/key.py +++ b/music21/key.py @@ -1033,7 +1033,7 @@ def relative(self) -> Key: in the middle of large datasets. Note that this uses .sharps as a speedup, so if that has been changed, there - will be a problem... + will be a problem: >>> k = key.Key('E-') >>> k diff --git a/music21/languageExcerpts/instrumentLookup.py b/music21/languageExcerpts/instrumentLookup.py index 5d1f2d565c..f83340447b 100644 --- a/music21/languageExcerpts/instrumentLookup.py +++ b/music21/languageExcerpts/instrumentLookup.py @@ -1263,7 +1263,7 @@ 'd': 'm-7', 'e': 'm-6', 'e-': 'M-6', - 'english': 'P-5', # this is how it works... + 'english': 'P-5', # this is how it works 'f': 'P-5', 'g': 'P-4', }, diff --git a/music21/layout.py b/music21/layout.py index d5a4591980..31324f0013 100644 --- a/music21/layout.py +++ b/music21/layout.py @@ -641,7 +641,7 @@ def getRichSystemLayout(inner_allSystemLayouts): for systemStartM, systemEndM in systemMeasureTuples: if systemStartM < pageStartM or systemEndM > pageEndM: continue - systemNumber += 1 # global, not on this page... + systemNumber += 1 # global, not on this page pageSystemNumber += 1 if fastMeasures is True: measureStacks = scoreIn.measures(systemStartM, systemEndM, @@ -896,7 +896,7 @@ def getMarginsAndSizeForPageId(self, pageId): dataCache[pageId] = dataTuple return dataTuple - def getPositionForSystem(self, pageId, systemId): + def getPositionForSystem(self, pageId: int, systemId: int) -> SystemSize: ''' first systems on a page use a different positioning. @@ -904,8 +904,7 @@ def getPositionForSystem(self, pageId, systemId): relative to the page margins N.B. right is NOT the width -- it is different. It is the offset to the right margin. - weird, inconsistent, but most useful...bottom is the hard part to compute... - + weird, inconsistent, but most useful. Bottom, however, is the hard part to compute. >>> lt = corpus.parse('demos/layoutTestMore.xml') >>> ls = layout.divideByPages(lt, fastMeasures = True) @@ -1147,7 +1146,7 @@ def getStaffDistanceFromPrevious(self, pageId, systemId, staffId): positionForStaffCache[cacheKey] = 0.0 return 0.0 - # nope, not first staff or first visible staff... + # nope, not first staff or first visible staff staffDistanceFromPrevious = 60.0 # sensible default? diff --git a/music21/lily/lilyObjects.py b/music21/lily/lilyObjects.py index 3eb5f22769..f40153f093 100644 --- a/music21/lily/lilyObjects.py +++ b/music21/lily/lilyObjects.py @@ -112,8 +112,8 @@ def setAttributes(self, m21Object): Returns a dictionary and sets self.lilyAttributes to that dictionary, for a m21Object of class classLookup using the mapping of self.m21toLy[classLookup] - - >>> class Mock(base.Music21Object): pass + >>> class Mock(base.Music21Object): + ... pass >>> m = Mock() >>> m.mockAttribute = 32 >>> m.mockAttribute2 = None @@ -260,11 +260,11 @@ def quoteString(self, stringIn): stringNew = stringIn.replace('"', r'\"') return '"' + stringNew + '" ' - def comment(self, stringIn): + def comment(self, stringIn: str) -> str: r''' returns a comment that is %{ stringIn.strip() %} - Don't put %} etc. in comments. That's just rude... + (Don't put %} etc. in comments -- it will break the system.) ''' return ' %{ ' + stringIn.strip() + ' %} ' @@ -725,13 +725,12 @@ def stringOutput(self): class LyScoreBody(LyObject): r''' - represents the contents of a \score { ...contents... } + represents the contents of a \score { contents } block can take one of the following attributes: music, scoreIdentifier, scoreBody, lilypondHeader, outputDef, error - >>> lsb = lily.lilyObjects.LyScoreBody(scoreIdentifier='score') >>> str(lsb) 'score' @@ -793,7 +792,7 @@ def stringOutput(self): class LyOutputDef(LyObject): r''' - This is an ugly grammar, since it does not close the curly bracket... + This is an ugly grammar, since it does not close the curly bracket. ''' def __init__(self, outputDefBody=None): @@ -1099,7 +1098,7 @@ def __init__(self, contextModList=None, contextModIdentifier=None, displayWith=T super().__init__() self.contextModList = contextModList self.contextModIdentifier = contextModIdentifier # String? - self.displayWith = displayWith # optional... but not supported without so far... + self.displayWith = displayWith # optional, but not supported without so far def stringOutput(self): if self.contextModList is not None: @@ -1425,7 +1424,7 @@ def stringOutput(self): else: outputString = c + ' ' outputString += self.newLyrics.stringOutput() - return outputString # previously this did not return... + return outputString # previously this did not return class LyContextChange(LyObject): @@ -2135,7 +2134,7 @@ def stringOutput(self): c += str(m) + ' ' return c -# skip markup_command_list and arguments for now... +# skip markup_command_list and arguments for now # skip markup_head_1_item # skip markup_head_1_list diff --git a/music21/lily/translate.py b/music21/lily/translate.py index 0ee150a8a6..c8e01e6fea 100644 --- a/music21/lily/translate.py +++ b/music21/lily/translate.py @@ -50,7 +50,7 @@ del find_spec -# TODO: speed up tests everywhere! move these to music21 base... +# TODO: speed up tests everywhere! move these to music21 base class _sharedCorpusTestObject: sharedCache: dict[str, stream.Stream] = {} @@ -283,19 +283,19 @@ def loadFromMusic21Object(self, m21ObjectIn): arbitrary music21 object. TODO: make lilypond automatically run makeNotation.makeTupletBrackets(s) - TODO: Add tests... + TODO: Add tests. ''' c = m21ObjectIn.classes if 'Stream' in c: if m21ObjectIn[variant.Variant]: - # has variants. so we need to make a deepcopy... + # has variants. so we need to make a deepcopy m21ObjectIn = variant.makeAllVariantsReplacements(m21ObjectIn, recurse=True) variant.makeVariantBlocks(m21ObjectIn) if ('Stream' not in c) or ('Measure' in c) or ('Voice' in c): scoreObj = stream.Score() partObj = stream.Part() - # no need for measures or voices... + # no need for measures or voices partObj.insert(0, m21ObjectIn) scoreObj.insert(0, partObj) self.loadObjectFromScore(scoreObj, makeNotation=False) @@ -307,7 +307,7 @@ def loadFromMusic21Object(self, m21ObjectIn): self.loadObjectFromScore(m21ObjectIn, makeNotation=False) elif 'Opus' in c: self.loadObjectFromOpus(m21ObjectIn, makeNotation=False) - else: # treat as part... + else: # treat as part scoreObj = stream.Score() scoreObj.insert(0, m21ObjectIn) self.loadObjectFromScore(scoreObj, makeNotation=False) @@ -376,7 +376,7 @@ def loadObjectFromScore(self, scoreIn=None, makeNotation=True): lpColorScheme = lyo.LyEmbeddedScm(self.colorDef) lpHeader = lyo.LyLilypondHeader() - # here's the heavy work... + # here's the heavy work lpScoreBlock = self.lyScoreBlockFromScore(scoreIn) lpOutputDefHead = lyo.LyOutputDefHead(defType='paper') @@ -409,7 +409,7 @@ def lyScoreBlockFromScore(self, scoreIn): lpGroupedMusicList = self.lyGroupedMusicListFromScoreWithParts(scoreIn) lpCompositeMusic.groupedMusicList = lpGroupedMusicList else: - # treat as a part... + # treat as a part lpPrefixCompositeMusic = self.lyPrefixCompositeMusicFromStream(scoreIn) lpCompositeMusic.prefixCompositeMusic = lpPrefixCompositeMusic @@ -578,7 +578,7 @@ def getLySpacersFromStream(self, streamIn, measuresOnly=True): >>> print(lpc.getLySpacersFromStream(streamIn)) s2. s2. s1 s1 s1 s1 s4 - TODO: Low-priority... rare, but possible: tuplet time signatures (3/10)... + TODO: Low-priority: rare, but possible: tuplet time signatures (3/10), etc. ''' returnString = '' @@ -613,7 +613,7 @@ def getLySpacersFromStream(self, streamIn, measuresOnly=True): def lyGroupedMusicListFromScoreWithParts(self, scoreIn, scoreInit=None): # noinspection PyShadowingNames,GrazieInspection r''' - More complex example showing how the score can be set up with ossia parts... + More complex example showing how the score can be set up with ossia parts: >>> lpc = lily.translate.LilypondConverter() >>> #_DOCS_SHOW b = corpus.parse('bach/bwv66.6') @@ -858,7 +858,7 @@ def lyPrefixCompositeMusicFromStream( # noinspection PyShadowingNames r''' returns an LyPrefixCompositeMusic object from - a stream (generally a part, but who knows...) + a stream (generally a part, but who knows!) >>> c = converter.parse('tinynotation: 3/4 C4 D E F2.') >>> c.staffLines = 4 @@ -906,7 +906,7 @@ def lyPrefixCompositeMusicFromStream( if hasattr(streamIn, 'staffLines') and streamIn.staffLines != 5: contextModList.append(fr"\override StaffSymbol #'line-count = #{streamIn.staffLines}") - if streamIn.staffLines % 2 == 0: # even stafflines need a change... + if streamIn.staffLines % 2 == 0: # even stafflines need a change pass lpNewLyrics = self.lyNewLyricsFromStream(streamIn, streamId=makeLettersOnlyId(streamIn.id)) @@ -972,7 +972,7 @@ def appendObjectsToContextFromStream(self, streamObject): >>> lpMusicList = lily.lilyObjects.LyMusicList() >>> lpc.context = lpMusicList >>> lpc.appendObjectsToContextFromStream(m) - >>> print(lpc.context) # internal spaces removed... + >>> print(lpc.context) # internal spaces removed << \new Voice { c'' 1 \bar "|." %{ end measure 1 %} } @@ -984,11 +984,11 @@ def appendObjectsToContextFromStream(self, streamObject): for groupedElements in OffsetIterator(streamObject): # print(groupedElements) - if len(groupedElements) == 1: # one thing at that moment... + if len(groupedElements) == 1: # one thing at that moment el = groupedElements[0] el.activeSite = streamObject self.appendM21ObjectToContext(el) - else: # voices or other More than one thing at once... + else: # voices or other More than one thing at once # if voices voiceList = [] variantList = [] @@ -1064,7 +1064,7 @@ def appendM21ObjectToContext(self, thisObject): lyObject = None if 'Measure' in c: - # lilypond does not put groups around measures... + # lilypond does not put groups around measures # it does however need barline ends # also, if variantMode is True, the last note in each "measure" should have \noBeam closeMeasureObj = self.closeMeasure() # could be None @@ -1170,15 +1170,15 @@ def appendContextFromNoteOrRest(self, noteOrRest): return # commented out until complete -# if self.variantMode is True: -# # TODO: attach \noBeam to note if it is the last note -# if isinstance(noteOrRest, note.NotRest): -# n = noteOrRest -# activeSite = n.activeSite -# offset = n.offset -# # failed at least once... -# if offset + n.duration.quarterLength == activeSite.duration.quarterLength: -# pass + # if self.variantMode is True: + # # TODO: attach \noBeam to note if it is the last note + # if isinstance(noteOrRest, note.NotRest): + # n = noteOrRest + # activeSite = n.activeSite + # offset = n.offset + # # failed at least once + # if offset + n.duration.quarterLength == activeSite.duration.quarterLength: + # pass self.setContextForTupletStart(noteOrRest) self.appendBeamCode(noteOrRest) @@ -1243,7 +1243,7 @@ def appendContextFromChord(self, chord): def lySimpleMusicFromNoteOrRest(self, noteOrRest): r''' - returns a lilyObjects.LySimpleMusic object for the generalNote containing... + returns a lilyObjects.LySimpleMusic object for the generalNote containing this hierarchy LyEventChord containing LySimpleChordElements containing @@ -1272,7 +1272,7 @@ def lySimpleMusicFromNoteOrRest(self, noteOrRest): \override Stem.color = "blue" dis'' ! ? 4 - Now make the note disappear... + Now make the note disappear: >>> n0.style.hideObjectOnPrint = True >>> sm = conv.lySimpleMusicFromNoteOrRest(n0) @@ -1464,7 +1464,7 @@ def lySimpleMusicFromChord(self, chordObj): evc = lyo.LyEventChord(noteChordElement=lpNoteChordElement) mlSM = lyo.LySimpleMusic(eventChord=evc) return mlSM - # TODO: Chord beaming... + # TODO: Chord beaming def postEventsFromObject(self, generalNote): r''' @@ -1474,7 +1474,7 @@ def postEventsFromObject(self, generalNote): postEvents = [] # remove this hack once lyrics work - # if generalNote.lyric is not None: # hack that uses markup... + # if generalNote.lyric is not None: # hack that uses markup # postEvents.append(r'_\markup { "' + generalNote.lyric + '" }\n ') # consider this hack removed. Yeah! @@ -1712,7 +1712,7 @@ def setContextForTupletStart(self, inObj): For now, no support for nested tuplets. They're an easy extension, but there's too much - else that is missing to do it now... + else that is missing to do it now. ''' if not inObj.duration.tuplets: return None @@ -2375,10 +2375,10 @@ def getSchemeForPadding(self, measureObject): type LyMultipliedDuration. You notate how many notes are left in the measure, for a quarter note, write "4" for an eighth, write "8", but for 3 eighths, write "8*3" ! - so we will measure in 32nd notes always... won't work for tuplets + so we will measure in 32nd notes always. It won't work for tuplets of course. - returns a scheme object or None if not needed + Returns a scheme object or None if not needed. >>> m = stream.Measure() >>> m.append(meter.TimeSignature('3/4')) @@ -2518,7 +2518,7 @@ def createPNG(self, fileName=None): lilyImage2 = ImageOps.expand(lilyImage, 10, 'white') # type: ignore lilyImage2.save(str(lilyFile)) except Exception: # pylint: disable=broad-exception-caught - pass # no big deal probably... + pass # no big deal probably return lilyFile def showPNG(self): diff --git a/music21/mei/base.py b/music21/mei/base.py index 161d46dcf4..4cb997e7f9 100644 --- a/music21/mei/base.py +++ b/music21/mei/base.py @@ -308,7 +308,7 @@ def __init__(self, theDocument=None): if isinstance(self.documentRoot, ElementTree): # pylint warns that :class:`Element` doesn't have a getroot() method, which is - # true enough, but... + # true enough, but it seems to work. self.documentRoot = self.documentRoot.getroot() if f'{MEI_NS}mei' != self.documentRoot.tag: @@ -411,7 +411,7 @@ def makeDuration( 3.0 >>> mei.base.makeDuration(base=2, dots=2).quarterLength # 'base' can be an int or float 3.5 - >>> mei.base.makeDuration(2.0, 10).quarterLength # you want ridiculous dots? Sure... + >>> mei.base.makeDuration(2.0, 10).quarterLength # you want ridiculous dots? Sure! 3.998046875 >>> mei.base.makeDuration(0.33333333333333333333, 0).quarterLength # works with fractions too Fraction(1, 3) @@ -1083,7 +1083,7 @@ def _transpositionFromAttrs(elem): # noinspection PyTypeChecker transSemi = int(elem.get('trans.semi', 0)) - # If the difference between transSemi and transDiat is greater than five per octave... + # If the difference between transSemi and transDiat is greater than five per octave # noinspection SpellCheckingInspection if abs(transSemi - transDiat) > 5 * (abs(transSemi) // 12 + 1): # ... we need to add octaves to transDiat so it's the proper size. Otherwise, @@ -1529,7 +1529,7 @@ def scoreDefFromElement(elem, slurBundle=None): This function returns a dictionary with objects that may relate to the entire score, to all parts at a particular moment, or only to a specific part at a particular moment. The dictionary - keys determine the object's scope. If the key is... + keys determine the object's scope. If the key is: * ``'whole-score objects'``, it applies to the entire score (e.g., page size); * ``'all-part objects'``, it applies to all parts at the moment this appears; diff --git a/music21/mei/test_base.py b/music21/mei/test_base.py index 9615ba5b9a..d936909276 100644 --- a/music21/mei/test_base.py +++ b/music21/mei/test_base.py @@ -121,7 +121,7 @@ def testRun1(self, mockMeta, mockScoreFE, mockConclude, ''' MeiToM21Converter.run(): that it works ''' - # ha... "test run"... get it? + # ha: "test run," get it? testConv = base.MeiToM21Converter() testConv.documentRoot = mock.MagicMock(spec_set=ETree.Element) testConv.documentRoot.find.return_value = 5 @@ -1080,9 +1080,9 @@ def testVerse4(self, mockEnviron): # ----------------------------------------------------------------------------- # Tests for noteFromElement() - # NOTE: For this TestCase, in the unit tests, if you get... - # AttributeError: 'str' object has no attribute 'call_count' - # ... it means a test failure, because the str should have been a MagicMock but was + # NOTE: For this TestCase, in the unit tests, if you get + # "AttributeError: 'str' object has no attribute 'call_count'" + # it means a test failure, because the str should have been a MagicMock but was # replaced with a string by the unit under test. @mock.patch('music21.note.Note') @@ -1588,8 +1588,8 @@ def testUnit6TestRestFromElement(self, mockSpace): # ----------------------------------------------------------------------------- # Tests for chordFromElement() - # NOTE: For this TestCase, in the unit tests, if you get... - # AttributeError: 'str' object has no attribute 'call_count' + # NOTE: For this TestCase, in the unit tests, if you get + # "AttributeError: 'str' object has no attribute 'call_count'" # ... it means a test failure, because the str should have been a MagicMock but was # replaced with a string by the unit under test. @@ -2531,7 +2531,7 @@ def testUnit3StaffFromElement(self, mockTrans, mockClef, mockKey, mockTime, 'clef': mockClef.return_value} # attributes on theMockInstrument that should be set by staffDefFromElement() # NB: because the part name wasn't recognized by music21, there won't be a part name on the - # Instrument... the only reason we get an Instrument at all is because of @trans.semi + # Instrument. The only reason we get an Instrument at all is because of @trans.semi expectedAttrs = [('transposition', mockTrans.return_value)] # D3 # 2.) run @@ -3931,7 +3931,7 @@ def testMeasureUnit1(self, mockVoice, mockMeasure, # this must match Measure.duration.quarterLength # prepare the mock Measure objects returned by mockMeasure mockMeasRets = [mock.MagicMock(name=f'Measure {i + 1}') for i in range(4)] - expected = mockMeasRets # finish preparing "expected" below... + expected = mockMeasRets # finish preparing "expected" below for meas in mockMeasRets: meas.duration = mock.MagicMock(spec_set=duration.Duration) meas.duration.quarterLength = 4.0 # must match activeMeter.barDuration.quarterLength @@ -4056,7 +4056,7 @@ def testMeasureUnit2(self, mockVoice, mockMeasure, # prepare the mock Measure objects returned by mockMeasure mockMeasRets = [mock.MagicMock(name=f'Measure {i + 1}') for i in range(4)] - expected = mockMeasRets # finish preparing "expected" below... + expected = mockMeasRets # finish preparing "expected" below for meas in mockMeasRets: meas.duration = mock.MagicMock(spec_set=duration.Duration) meas.duration.quarterLength = base._DUR_ATTR_DICT[None] # must be _DUR_ATTR_DICT[None] @@ -4402,7 +4402,7 @@ def testScoreIntegration1(self): actual = base.scoreFromElement(elem, slurBundle) - # This is complicated... I'm sorry... but it's a rather detailed test of the whole system, + # This is complicated. I'm sorry. But it's a rather detailed test of the whole system, # so I hope it's worth it! self.assertEqual(2, len(actual.parts)) self.assertEqual(3, len(actual)) # parts plus "slurBundle" diff --git a/music21/metadata/__init__.py b/music21/metadata/__init__.py index 6405466567..c98750fb47 100755 --- a/music21/metadata/__init__.py +++ b/music21/metadata/__init__.py @@ -1070,7 +1070,7 @@ def search( ... ) (True, 'composer') - These don't work (Richard didn't have the sense of rhythm to write this...) + These don't work (Richard didn't have the sense of rhythm to write this!) >>> md.search( ... 'Wagner', @@ -2541,8 +2541,8 @@ def merge(self, other, favorSelf=False): def getSourcePath(self, streamObj) -> str: ''' - Get a string of the path after the corpus for the piece...useful for - searching on corpus items without proper composer data... + Get a string of the path after the corpus for the piece. Useful for + searching on corpus items without proper composer data. >>> rmd = metadata.RichMetadata() >>> b = corpus.parse('bwv66.6') diff --git a/music21/metadata/bundles.py b/music21/metadata/bundles.py index 5763e3fec2..a7ee9d9cd0 100644 --- a/music21/metadata/bundles.py +++ b/music21/metadata/bundles.py @@ -1316,7 +1316,7 @@ def write(self, filePath=None): if self.filePath is not None: filePath = self.filePath environLocal.printDebug(['MetadataBundle: writing:', filePath]) - storedCorpusClient = self._corpus # no weakrefs allowed... + storedCorpusClient = self._corpus # no weakrefs allowed self._corpus = None uncompressed = pickle.dumps(self, protocol=3) # 3 is a safe protocol for some time to come. diff --git a/music21/metadata/caching.py b/music21/metadata/caching.py index fd42f0bd8b..f51d40cd83 100644 --- a/music21/metadata/caching.py +++ b/music21/metadata/caching.py @@ -319,7 +319,7 @@ def process_parallel(jobs, processCount=None): ''' processCount = processCount or common.cpus() processCount = max(processCount, 1) - # do not start more processes than jobs... + # do not start more processes than jobs remainingJobs = len(jobs) processCount = min(processCount, remainingJobs) diff --git a/music21/metadata/primitives.py b/music21/metadata/primitives.py index ea7208bc46..4d51c105d4 100644 --- a/music21/metadata/primitives.py +++ b/music21/metadata/primitives.py @@ -190,7 +190,7 @@ def _stripError(self, >>> d._stripError('63?') (63, 'uncertain') - Milliseconds are not retained -- this is for musicology, not computers... + Milliseconds are not retained -- this is for musicology, not computers: >>> d._stripError('4.43') (4, None) @@ -213,7 +213,7 @@ def _stripError(self, value = value.replace(found, '') uncertainty = 'priority' - # cannot convert string '4.43' directly to int... + # cannot convert string '4.43' directly to int value = float(value) return int(value), uncertainty @@ -397,7 +397,7 @@ def datetime(self): >>> a.datetime Traceback (most recent call last): - TypeError: ...argument 'day' (pos 3)... + TypeError: function missing required argument 'day' (pos 3) ''' post = [] # order here is order for datetime @@ -1058,7 +1058,7 @@ class Contributor(prebase.ProtoM21Object): # !!!LOR: Orchestrator. # !!!TRN: Translator of text. - # TODO: add editor... + # TODO: add editor roleAbbreviationsDict = { 'com': 'composer', diff --git a/music21/metadata/properties.py b/music21/metadata/properties.py index 87f1195ee0..91412fbead 100644 --- a/music21/metadata/properties.py +++ b/music21/metadata/properties.py @@ -851,7 +851,7 @@ class PropertyDescription: oldMusic21Abbrev='osc', isContributor=False), - # movementNumber: movement number (e.g. '4', or 'mov. 4', or...) + # movementNumber: movement number (e.g. '4', or 'mov. 4') PropertyDescription( uniqueName='movementNumber', name='OMV', diff --git a/music21/meter/base.py b/music21/meter/base.py index b41babc49e..3453410fc7 100644 --- a/music21/meter/base.py +++ b/music21/meter/base.py @@ -644,7 +644,7 @@ def ratioString(self): >>> threeFour.ratioString '3/4' - It can also be set to load a new one, but '.load()' is better... + It can also be set to load a new one, but '.load()' is better: >>> threeFour.ratioString = '5/8' # now this variable name is dumb! >>> threeFour.numerator @@ -809,7 +809,7 @@ def barDuration(self, value: duration.Duration): @property def beatLengthToQuarterLengthRatio(self) -> float: ''' - Returns 4.0 / denominator... seems a bit silly... + Returns 4.0 / denominator. Might seem a bit silly but used often. >>> a = meter.TimeSignature('3/2') >>> a.beatLengthToQuarterLengthRatio @@ -820,7 +820,7 @@ def beatLengthToQuarterLengthRatio(self) -> float: @property def quarterLengthToBeatLengthRatio(self) -> float: ''' - Returns denominator/4.0... seems a bit silly... + Returns denominator/4.0. ''' return self.denominator / 4.0 @@ -1113,7 +1113,7 @@ def beatSubDivisionDurations(self) -> list[duration.Duration]: post = [] src = self.beatDivisionDurations for d in src: - # this is too slow... TODO: fix, but make sure all durations are unique. + # this is too slow. TODO: fix, but make sure all durations are unique. post.append(d.augmentOrDiminish(0.5)) post.append(d.augmentOrDiminish(0.5)) return post @@ -1793,14 +1793,14 @@ def getAccentWeight(self, qLenPos, level=0, forcePositionMatch=False, >>> [ts1.getAccentWeight(x) for x in range(3)] [1.0, 0.5, 0.5] - Returns an error... + Calling getAccentWeight on durations beyond the score returns an error: >>> [ts1.getAccentWeight(x) for x in range(6)] Traceback (most recent call last): music21.exceptions21.MeterException: cannot access from qLenPos 3.0 where total duration is 3.0 - ...unless permitMeterModulus is employed + The error is removed if permitMeterModulus is employed: >>> [ts1.getAccentWeight(x, permitMeterModulus=True) for x in range(6)] [1.0, 0.5, 0.5, 1.0, 0.5, 0.5] @@ -1834,8 +1834,8 @@ def getBeat(self, offset): If you want a fractional number for the beat, see `getBeatProportion`. - TODO: In v7 -- getBeat will probably do what getBeatProportion does now... - but just with 1 added to it. + TODO: In a future version -- getBeat will probably do what getBeatProportion does now, + but just with 1 added to it. >>> a = meter.TimeSignature('3/4', 3) >>> a.getBeat(0) @@ -2153,7 +2153,7 @@ def _reprInternal(self): return str(self.text) -# TODO: Implement or delete... +# TODO: Implement or delete # class NonPowerOfTwoTimeSignature(TimeSignature): # pass # class AutoAdjustTimeSignature(TimeSignature): diff --git a/music21/meter/core.py b/music21/meter/core.py index 6a755113a0..2637ccc8e7 100644 --- a/music21/meter/core.py +++ b/music21/meter/core.py @@ -862,7 +862,7 @@ def partition( >>> str(a) '{1/8+1/8+1/8+...+1/8}' - Demo of loadDefault: if impossible, then do it another way... + Demo of loadDefault: if impossible, then do it another way: >>> c = meter.MeterSequence('3/128') >>> c.partition(2) @@ -939,7 +939,7 @@ def subdividePartitionsEqual(self, divisions: int|None = None) -> None: >>> ms[1] - There is not a way (the authors know of...) to get to the next level. + There is not a way (the authors know of) to get to the next level. You would just need to do them individually. >>> ms[0].subdividePartitionsEqual(2) @@ -977,7 +977,7 @@ def subdividePartitionsEqual(self, divisions: int|None = None) -> None: elif partitionNumerator in (6, 9, 12, 15, 18, 21, 24, 27): divisionsLocal = partitionNumerator // 3 else: - # TODO: get from the smallest primer number... + # TODO: get from the smallest prime number divisionsLocal = partitionNumerator else: divisionsLocal = divisions @@ -1062,7 +1062,7 @@ def subdivideNestedHierarchy(self, depth, firstPartitionForm=None, >>> ms - I think you get the picture... + I think you get the picture! The effects above are not cumulative. Users can skip directly to whatever level of hierarchy they want. @@ -1184,7 +1184,7 @@ def partitionStr(self): 'Single' ''' count = len(self) - countName = ('Empty', # should not happen... + countName = ('Empty', # should not happen 'Single', 'Duple', 'Triple', 'Quadruple', 'Quintuple', 'Sextuple', 'Septuple', 'Octuple') @@ -2009,8 +2009,8 @@ def offsetToWeight(self, qLenPos): >>> a.offsetToWeight(1.5) Fraction(1, 3) - ??? Not sure what this does... ''' + # Not sure what this does! qLenPos = opFrac(qLenPos) if qLenPos >= self.duration.quarterLength or qLenPos < 0: raise MeterException( diff --git a/music21/meter/tools.py b/music21/meter/tools.py index 3585cea5cc..f0ff3e9f41 100644 --- a/music21/meter/tools.py +++ b/music21/meter/tools.py @@ -159,7 +159,7 @@ def slashMixedToFraction(valueSrc: str) -> tuple[NumDenomTuple, bool]: 'Cannot parse this file -- this error often comes ' + 'up if the musicxml pickled file is out of date after a change ' + 'in musicxml/__init__.py . ' - + 'Clear your temp directory of .p and .p.gz files and try again...; ' + + 'Clear your temp directory of .p and .p.gz files and try again. ' + f'Time Signature: {valueSrc} ') post: list[NumDenom] = [] @@ -249,7 +249,7 @@ def fractionSum(numDenomTuple: NumDenomTuple) -> NumDenom: if len(dListUnique) == 1: n = sum(nList) d = dList[0] - # Does not reduce to lowest terms... + # Does not reduce to lowest terms return (n, d) else: # there might be a better way to do this dRed = math.lcm(*dListUnique) diff --git a/music21/midi/__init__.py b/music21/midi/__init__.py index 78adb03f80..d9f2e6b1a6 100644 --- a/music21/midi/__init__.py +++ b/music21/midi/__init__.py @@ -140,7 +140,7 @@ def getNumber(midiStr, length): else: summation = (summation << 8) + ord(midiStrOrNum) return summation, midiStr[length:] - else: # midiStr is a number... + else: # midiStr is a number midNum = midiStr summation = midNum - ((midNum >> (8 * length)) << (8 * length)) bigBytes = midNum - summation @@ -198,7 +198,7 @@ def getVariableLengthNumber(midiBytes): if isinstance(midiBytes, str): midiBytes = midiBytes.encode('utf-8') - while i < 999: # should return eventually... was while True + while i < 999: # should return eventually (was "while True") x = midiBytes[i] # environLocal.printDebug(['getVariableLengthNumber: examined char:', # charToBinary(midiBytes[i])]) @@ -479,7 +479,7 @@ def __init__(self, self.parameter1: int|bytes|None = None # pitch or first data value self.parameter2: int|bytes|None = None # velocity or second data value - # data is a property... + # data is a property # if this is a Note on/off, need to store original # pitch space value in order to determine if this has a microtone diff --git a/music21/midi/percussion.py b/music21/midi/percussion.py index 5e94e577bd..c4220a3042 100644 --- a/music21/midi/percussion.py +++ b/music21/midi/percussion.py @@ -103,7 +103,7 @@ def midiPitchToInstrument(self, midiPitch): >>> cowbell - Or it can just take an integer (representing MIDI note) for the pitch instead... + Or it can just take an integer (representing MIDI note) for the pitch instead: >>> moreCowbell = pm.midiPitchToInstrument(56) >>> moreCowbell diff --git a/music21/midi/translate.py b/music21/midi/translate.py index 12e0461ecc..2159c1b09d 100644 --- a/music21/midi/translate.py +++ b/music21/midi/translate.py @@ -545,7 +545,7 @@ def midiEventsToChord( (time_pitch2_off, pitch2_note_off_event) ), - ...etc... + (etc.) :func:`~music21.midi.translate.midiEventsToNote`. @@ -2305,7 +2305,7 @@ def channelInstrumentData( else: substreamList.append(obj) else: - # should not ever run if prepareStreamForMidi() was run... + # should not ever run if prepareStreamForMidi() was run substreamList.append(s) # pragma: no cover # Music tracks diff --git a/music21/musedata/__init__.py b/music21/musedata/__init__.py index d825b93029..38788ab053 100644 --- a/music21/musedata/__init__.py +++ b/music21/musedata/__init__.py @@ -27,7 +27,9 @@ ''' from __future__ import annotations +from collections.abc import Sequence import os +import typing as t import unittest from music21 import environment @@ -161,7 +163,7 @@ def _getPitchParameters(self): else: raise MuseDataException('cannot get pitch parameters from this kind of record') - pStr = [data[0]] # first element will be A...G + pStr = [data[0]] # first element will be A–G if '#' in data: pStr.append('#') elif '##' in data: @@ -936,13 +938,33 @@ def getDirective(self): return alphas.strip() def getSource(self): - ''' + r''' + Return the source (original print encoding) for the score. + >>> fp1 = (common.getSourceFilePath() / 'musedata' / 'testPrimitive' - ... / 'test01' / '01.md') + ... / 'test01' / '03.md') >>> mdw = musedata.MuseDataWork() >>> mdw.addFile(fp1) >>> mdw.getParts()[0].getSource() - 'Breitkopf & H...rtel, Vol. 13' + 'Breitkopf & Härtel, Vol. 13' + + Note that the publisher is Härtel. MuseData predates the standardization + of encoding as UTF-8, so many + MuseData files are in Windows (ISO-8859-1) encodings. + Music21 tries first + in utf-8 and if there are errors will try again in ISO-8859-1, and if it + fails it will try to read ignoring any errors (leaving "Hrtel"). + In this case, both UTF-8 and ISO-8859-1 support this character (Latin-1 space + in Unicode). + + If you know the encoding you can pass that to MuseDataWork or MuseDataFile. + It is not yet a property you can specify in converter. + + >>> mdw = musedata.MuseDataWork() + >>> mdw.encoding = 'ISO-8859-1' + >>> mdw.addFile(fp1) + >>> mdw.getParts()[0].getSource() + 'Breitkopf & Härtel, Vol. 13' ''' if self.stage == 1: # get the header number: not sure what this is for now @@ -1445,12 +1467,12 @@ class MuseDataFile(prebase.ProtoM21Object): When read, one or more MuseDataPart objects are created and stored on self.parts. ''' - def __init__(self): self.parts = [] # a lost of MuseDataPart objects self.filename = None self.file = None + self.encoding: str = 'utf-8' def _reprInternal(self): return '' @@ -1465,7 +1487,7 @@ def read(self): # call readstr with source string from file fileContents = self.file.read() try: - fileContents = fileContents.decode('utf-8') + fileContents = fileContents.decode(self.encoding) except UnicodeDecodeError: fileContents = fileContents.decode('ISO-8859-1', 'ignore') return self.readstr(fileContents) @@ -1528,20 +1550,24 @@ class MuseDataWork(prebase.ProtoM21Object): ''' def __init__(self): - self.files = [] # a list of one or more MuseDataFile objects + self.files: list[MuseDataFile] = [] + self.encoding: str = 'utf-8' - def addFile(self, fp): + def addFile(self, fp: str | Sequence[str]) -> None: ''' Open and read this file path or list of paths as MuseDataFile objects and set self.files ''' + fpList: Sequence[str] if not common.isIterable(fp): - fpList = [fp] + fp_single = t.cast(str, fp) + fpList = [fp_single] else: fpList = fp for fpInner in fpList: mdf = MuseDataFile() + mdf.encoding = self.encoding # environLocal.printDebug('processing MuseData file: %s' % fp) mdf.open(fpInner) mdf.read() # process string and break into parts diff --git a/music21/musedata/base40.py b/music21/musedata/base40.py index 60b064ae2b..2aa9b83912 100644 --- a/music21/musedata/base40.py +++ b/music21/musedata/base40.py @@ -146,7 +146,7 @@ 36: 'A7', 39: 'd8', - 40: 'P8', # wraps around... + 40: 'P8', # wraps around } diff --git a/music21/musedata/testPrimitive/test01/01.md b/music21/musedata/testPrimitive/test01/01.md index 3e3c74cbaf..061abef517 100644 --- a/music21/musedata/testPrimitive/test01/01.md +++ b/music21/musedata/testPrimitive/test01/01.md @@ -3,7 +3,7 @@ 04/16/93 E. Correia WK#:581 MV#:3c -Breitkopf & Hãrtel, Vol. 13 +Breitkopf & Härtel, Vol. 13 Clarinet Quintet Trio II Clarinet in A @@ -79,4 +79,4 @@ measure 12 C5 6 q d rest 6 q mheavy4 :||: -/END \ No newline at end of file +/END diff --git a/music21/musedata/testPrimitive/test01/02.md b/music21/musedata/testPrimitive/test01/02.md index 1aae375f23..8a2f506f95 100644 --- a/music21/musedata/testPrimitive/test01/02.md +++ b/music21/musedata/testPrimitive/test01/02.md @@ -3,7 +3,7 @@ 04/16/93 E. Correia WK#:581 MV#:3c -Breitkopf & Hãrtel, Vol. 13 +Breitkopf & Härtel, Vol. 13 Clarinet Quintet Trio II Violino I @@ -64,4 +64,4 @@ measure 12 C#4 2 q u rest 2 q mheavy4 :||: -/END \ No newline at end of file +/END diff --git a/music21/musedata/testPrimitive/test01/03.md b/music21/musedata/testPrimitive/test01/03.md index 14976bd01e..3e164f1a13 100644 --- a/music21/musedata/testPrimitive/test01/03.md +++ b/music21/musedata/testPrimitive/test01/03.md @@ -3,7 +3,7 @@ 04/16/93 E. Correia WK#:581 MV#:3c -Breitkopf & Hãrtel, Vol. 13 +Breitkopf & Härtel, Vol. 13 Clarinet Quintet Trio II Violino II diff --git a/music21/musedata/testPrimitive/test01/04.md b/music21/musedata/testPrimitive/test01/04.md index 2a13f69098..175c88aafd 100644 --- a/music21/musedata/testPrimitive/test01/04.md +++ b/music21/musedata/testPrimitive/test01/04.md @@ -3,7 +3,7 @@ 04/16/93 E. Correia WK#:581 MV#:3c -Breitkopf & H\3artel, vol. 13 +Breitkopf & Härtel, vol. 13 Clarinet Quintet Trio II Viola diff --git a/music21/musedata/testPrimitive/test01/05.md b/music21/musedata/testPrimitive/test01/05.md index fe07a19ae8..12b1181641 100644 --- a/music21/musedata/testPrimitive/test01/05.md +++ b/music21/musedata/testPrimitive/test01/05.md @@ -3,7 +3,7 @@ 04/16/93 E. Correia WK#:581 MV#:3c -Breitkopf & H\3artel, Vol. 13 +Breitkopf & Härtel, Vol. 13 Clarinet Quintet Trio II Violoncello @@ -53,4 +53,4 @@ measure 12 A2 2 q u rest 2 q mheavy4 :||: -/END \ No newline at end of file +/END diff --git a/music21/musedata/translate.py b/music21/musedata/translate.py index 4d8697322d..e0184451cb 100644 --- a/music21/musedata/translate.py +++ b/music21/musedata/translate.py @@ -581,7 +581,7 @@ def testBackBasic(self): # # note: this is importing a large work, but this seems to presently # # be the only one with dynamics # - # # TODO: Turn back on when a smaller work is found... + # # TODO: Turn back on when a smaller work is found # from music21 import corpus # s = corpus.parse('symphony94', 3) # sFlat = s.flatten() diff --git a/music21/musicxml/archiveTools.py b/music21/musicxml/archiveTools.py index fe4617bca6..1c41fac304 100644 --- a/music21/musicxml/archiveTools.py +++ b/music21/musicxml/archiveTools.py @@ -138,7 +138,7 @@ def uncompressMXL(filename: str|pathlib.Path, continue myZip.extract(member=storedName, path=extractPath) if not found_one_file: - # only rename one file...hope it is the right one. + # only rename one file: hope it is the right one. extractPath_pathlib = pathlib.Path(extractPath) wrongName = extractPath_pathlib / storedName correctName = extractPath_pathlib / unarchivedName diff --git a/music21/musicxml/helpers.py b/music21/musicxml/helpers.py index 5d8a6ef496..6c6135f127 100644 --- a/music21/musicxml/helpers.py +++ b/music21/musicxml/helpers.py @@ -99,7 +99,7 @@ def indent(elem, level=0): subElem = None for subElem in elem: indent(subElem, level + 1) - if subElem is not None: # last el... + if subElem is not None: # last el subElem.tail = i if not elem.tail or not elem.tail.strip(): @@ -325,7 +325,7 @@ def setM21AttributeFromAttribute( >>> pl.pageNumber 4 - More complex... + More complex: >>> convBool = musicxml.xmlObjects.yesNoToBoolean >>> setb(pl, e, 'new-page', 'isNew', transform=convBool) diff --git a/music21/musicxml/m21ToXml.py b/music21/musicxml/m21ToXml.py index ea2c7dc04b..d36be8ea1a 100644 --- a/music21/musicxml/m21ToXml.py +++ b/music21/musicxml/m21ToXml.py @@ -124,7 +124,7 @@ def typeToMusicXMLType(value: str) -> str: def normalizeColor(color: str) -> str: ''' - Normalize a css3 name to hex or leave it alone... + Normalize a css3 name to hex or leave it alone. >>> musicxml.m21ToXml.normalizeColor('') '' @@ -496,7 +496,7 @@ def fromStream(self, st): st2.metadata = copy.deepcopy(getMetadataFromContext(st)) return self.fromScore(st2) - elif st.getElementsByClass(stream.Stream).first().isFlat: # like a part w/ measures... + elif st.getElementsByClass(stream.Stream).first().isFlat: # like a part w/ measures st2 = stream.Part() st2.mergeAttributes(st) st2.elements = copy.deepcopy(st) @@ -509,7 +509,7 @@ def fromStream(self, st): return self.fromPart(st2) else: - # probably a problem? or a voice... + # probably a problem? or a voice if not st.getElementsByClass(clef.Clef).getElementsByOffset(0.0): bestClef = True else: @@ -998,7 +998,7 @@ def setEditorial(self, mxObject, m21Object): ''' if m21Object.hasEditorialInformation is False: return - # MusicXML allows only one footnote or level, so we take the first... + # MusicXML allows only one footnote or level, so we take the first. e = m21Object.editorial if 'footnotes' not in e and 'comments' not in e: @@ -1746,7 +1746,7 @@ def setScoreHeader(self) -> None: for tb in self.textBoxes: # a stream of text boxes self.xmlRoot.append(self.textBoxToXmlCredit(tb)) - # the hard one... + # the hard one: self.setPartList() def textBoxToXmlCredit(self, textBox: text.TextBox) -> Element: @@ -1914,7 +1914,7 @@ def setDefaults(self): mxDefaults.append(mxStaffLayout) self.addStyleToXmlDefaults(mxDefaults) - return mxDefaults # mostly for testing... + return mxDefaults # mostly for testing def addStyleToXmlDefaults(self, mxDefaults): # noinspection PyShadowingNames @@ -2128,7 +2128,7 @@ def staffGroupToXmlPartGroup(self, staffGroup): ''' Create and configure an mxPartGroup object for the 'start' tag from a staff group spanner. Note that this object - is not completely formed by this procedure. (number isn't done...) + is not completely formed by this procedure (number isn't done). >>> b = corpus.parse('bwv66.6') >>> SX = musicxml.m21ToXml.ScoreExporter(b) @@ -2202,7 +2202,7 @@ def staffGroupToXmlPartGroup(self, staffGroup): def setIdentification(self) -> Element: # noinspection SpellCheckingInspection, PyShadowingNames ''' - Returns an identification object from self.scoreMetadata. And appends to the score... + Returns an identification object from self.scoreMetadata and appends it to the score. For defaults: @@ -2224,8 +2224,7 @@ def setIdentification(self) -> Element: >>> c = metadata.Contributor(role='arranger', name='Aliyah Shanti') >>> md.addContributor(c) - need a fresh ScoreExporter ...otherwise appends to existing mxIdentification - + Need a fresh ScoreExporter, or, it will otherwise append to the existing mxIdentification >>> SX = musicxml.m21ToXml.ScoreExporter() >>> SX.scoreMetadata = md @@ -2290,7 +2289,7 @@ def setIdentification(self) -> Element: mxRights.set('type', c.role) mxRights.text = str(c) - # Encoding does its own append... + # Encoding does its own append. self.setEncoding() # TODO: source # TODO: relation @@ -2417,7 +2416,7 @@ def setEncoding(self): mxEncoding = Element('encoding') mxEncodingDate = SubElement(mxEncoding, 'encoding-date') - mxEncodingDate.text = str(datetime.date.today()) # right format... + mxEncodingDate.text = str(datetime.date.today()) # right format # TODO: encoder if self.scoreMetadata is not None: @@ -2443,7 +2442,7 @@ def setEncoding(self): for mxSupports in mxSupportsList: mxEncoding.append(mxSupports) - return mxEncoding # for testing... + return mxEncoding # for testing def getSupports(self): ''' @@ -2889,7 +2888,7 @@ def getXmlScorePart(self): ''' part = self.stream mxScorePart = Element('score-part') - # TODO: identification -- specific metadata... could go here... + # TODO: identification -- specific metadata could go here mxScorePart.set('id', self.xmlRoot.get('id')) mxPartName = SubElement(mxScorePart, 'part-name') @@ -3069,7 +3068,7 @@ def __init__(self, measureObj: stream.Measure|None = None, parent: PartExporter|None = None): super().__init__() - if measureObj is None: # no point, but... + if measureObj is None: # no point, but give an empty one anyhow. self.stream = stream.Measure() else: self.stream = measureObj @@ -3142,7 +3141,7 @@ def mainElementsParse(self): else: backupAfterwards = True - # Assumes voices are flat... + # Assumes voices are flat. self.parseFlatElements(v, backupAfterwards=backupAfterwards) def moveForward(self, byOffset: OffsetQL): @@ -3207,7 +3206,7 @@ def parseFlatElements( ''' Deals with parsing all the elements in .elements, assuming that .elements is flat. - m here can be a Measure or Voice, but flat... + `m` here can be a Measure or Voice, but it must be flat. If m is a 'Voice' class, we use the .id element to set self.currentVoiceId and then send a backup tag to go back to the beginning of the measure. @@ -3522,7 +3521,12 @@ def _spannerStartParameters(spannerClass, sp): >>> ottava = spanner.Ottava(type='8va') >>> st = ssp('Ottava', ottava) - >>> st['type'] # this is the opposite of what you might expect... + + Note that an ottava up in MusicXML is type "down", perhaps the opposite of what + you might expect. It means that the music should be engraved "down" from + where the sounding pitches would normally be engraved. + + >>> st['type'] 'down' >>> st['size'] 8 @@ -3694,7 +3698,7 @@ def objectAttachedSpannersToNotations( # placement??? notations.append(mxGlissando) - # These add to Ornaments... + # These add to Ornaments for su in sb.getByClass('TremoloSpanner'): mxTrem = Element('tremolo') @@ -3709,7 +3713,7 @@ def objectAttachedSpannersToNotations( # this is always an error for tremolos environLocal.printDebug( ['spanner w/ a component that is neither a start nor an end.', su, obj]) - # Tremolos get in a separate ornaments tag... + # Tremolos get in a separate ornaments tag. ornaments.append(mxTrem) for su in sb.getByClass('TrillExtension'): @@ -3738,7 +3742,7 @@ def objectAttachedSpannersToNotations( continue # do not put a wavy-line tag on mid-trill notes ornaments.append(mxWavyLine) if isFirstANDLast is True: - # make another one... + # make another one: mxWavyLine = Element('wavy-line') mxWavyLine.set('number', str(su.idLocal)) mxWavyLine.set('type', 'stop') @@ -3954,7 +3958,7 @@ def noteToXml(self, n: note.GeneralNote, noteIndexInChord=0, chordParent=None): Cannot convert complex durations to MusicXML. Try exporting with makeNotation=True or manually running splitAtDurations() - TODO: Test with spanners... + TODO: Test with spanners ''' addChordTag = (noteIndexInChord != 0) setb = setAttributeFromAttribute @@ -4008,7 +4012,7 @@ def noteToXml(self, n: note.GeneralNote, noteIndexInChord=0, chordParent=None): except AttributeError: environLocal.warn(f'Duration set as Grace while not being a GraceDuration {d}') - # TODO: cue... / cue-grace + # TODO: cue / cue-grace self.setPrintObject(mxNote, n) if n.hasStyleInformation and n.style.hideObjectOnPrint is True: @@ -4063,7 +4067,7 @@ def noteToXml(self, n: note.GeneralNote, noteIndexInChord=0, chordParent=None): mxNote.append(mxType) for unused_dotCounter in range(d.dots): SubElement(mxNote, 'dot') - # TODO: dot placement... + # TODO: dot placement if (isinstance(n, note.Note) and n.pitch.accidental is not None @@ -4086,7 +4090,7 @@ def noteToXml(self, n: note.GeneralNote, noteIndexInChord=0, chordParent=None): mxTimeModification = self.tupletToTimeModification(tempTuplet) mxNote.append(mxTimeModification) - # stem... + # stem: stemDirection = None # if we are not in a chord, or we are the first note of a chord, get stem # direction from the chordOrNote object @@ -4156,7 +4160,7 @@ def noteToXml(self, n: note.GeneralNote, noteIndexInChord=0, chordParent=None): if addChordTag is False: for lyricObj in chordOrN.lyrics: if lyricObj.text is None: - continue # happens sometimes... + continue # happens sometimes! mxLyric = self.lyricToXml(lyricObj) mxNote.append(mxLyric) # TODO: play @@ -4922,15 +4926,15 @@ def noteToNotations( mxArticulations.append(self.articulationToXmlArticulation(aObj)) # TODO: attrGroup: print-object (for individual notations) - # TODO: editorial (hard! -- requires parsing again in order...) + # TODO: editorial (will be hard! -- requires parsing again in order.) # - # for ties get for each note of chord too... + # for ties get for each note of chord too if n.tie is not None: tiedList = self.tieToXmlTied(n.tie) notations.extend(tiedList) - # handled elsewhere, because it's on the overall duration on chord... + # handled elsewhere, because it's on the overall duration on chord if chordParent is not None: notations.extend(self.objectAttachedSpannersToNotations(chordParent, noteIndexInChord)) @@ -5045,7 +5049,7 @@ def tieToXmlTied(self, m21Tie: tie.Tie): mxTied.set('line-type', m21Tie.style) # wavy is not supported as a tie type. - # Tie style needs to be dealt with after changes to Tie object... + # Tie style needs to be dealt with after changes to Tie object # TODO: attrGroup: dashed-formatting # TODO: attrGroup: position @@ -5201,7 +5205,7 @@ def expressionToXml(self, expression: expressions.Expression) -> Element: >>> MEX.dump(mxExpression) - Some special types... + Some special types: >>> f = expressions.Fermata() >>> MEX = musicxml.m21ToXml.MeasureExporter() @@ -5270,9 +5274,9 @@ def expressionToXml(self, expression: expressions.Expression) -> Element: ('Shake', 'shake'), ('Schleifer', 'schleifer'), ('Tremolo', 'tremolo'), # non-spanner - # non-ornaments... + # non-ornaments ('Fermata', 'fermata'), - # keep last... + # keep last ('Ornament', 'other-ornament'), ]) @@ -5384,7 +5388,7 @@ def setLineStyle(self, mxObject, m21Object): # >>> MEX = musicxml.m21ToXml.MeasureExporter() # >>> fb = instruments.fretted.FretBoard(1, 2, 3) # - # configure it here... + # configure it here # # >>> mxFret = MEX.fretboardToXmlTechnical(fb) # >>> MEX.dump(mxFret) @@ -5799,7 +5803,7 @@ def chordSymbolToXml(self, - Now give function... + Now give function: >>> cs.romanNumeral = 'I64' >>> mxHarmony = MEX.chordSymbolToXml(cs) @@ -5900,7 +5904,7 @@ def chordSymbolToXml(self, csRoot = cs.root() csBass = cs.bass(find=False) - # TODO: do not look at ._attributes... + # TODO: do not look at ._attributes if cs._roman is not None: mxFunction = SubElement(mxHarmony, 'function') mxFunction.text = cs.romanNumeral.figure @@ -5943,7 +5947,7 @@ def chordSymbolToXml(self, mxInversion.text = str(csInv) if csBass is not None and (csRoot is None or csRoot.name != csBass.name): - # TODO.. reuse above from Root... + # TODO.. reuse above from Root mxBass = SubElement(mxHarmony, 'bass') mxStep = SubElement(mxBass, 'bass-step') mxStep.text = str(csBass.step) @@ -6035,7 +6039,7 @@ def dynamicToXml(self, d: dynamics.Dynamic) -> Element: ''' return a nested tag: - or whatever... + or whatever: >>> ppp = dynamics.Dynamic('ppp') >>> print('%.2f' % ppp.volumeScalar) @@ -6083,7 +6087,7 @@ def dynamicToXml(self, d: dynamics.Dynamic) -> Element: # TODO: smufl self.setPrintStyleAlign(mxDynamics, d) - # TODO: attrGroup: placement (but done for direction, so okay... + # TODO: attrGroup: placement (but done for direction, so okay) # TODO: attrGroup: text-decoration # TODO: attrGroup: enclosure @@ -6143,9 +6147,7 @@ def segnoToXml(self, segno: repeat.Segno) -> Element: def codaToXml(self, coda: repeat.Coda) -> Element: ''' returns a coda inside a direction-type inside a direction IF coda.useSymbol is - True; otherwise returns a textExpression... - - appends to score + True; otherwise returns a TextExpression and appends to score: >>> c = repeat.Coda() >>> MEX = musicxml.m21ToXml.MeasureExporter() @@ -6187,8 +6189,8 @@ def tempoIndicationToXml(self, ti: tempo.TempoIndication) -> Element: ''' returns a tag for a single tempo indication. - note that TWO direction tags may be added to xmlroot, the second one - as a textExpression.... but only the first will be returned. + note that **two** direction tags may be added to xmlroot, the second one + as a textExpression, but only the first will be returned. >>> mm = tempo.MetronomeMark('slow', 40, note.Note(type='half')) >>> mm.style.justify = 'left' @@ -6246,7 +6248,7 @@ def tempoIndicationToXml(self, ti: tempo.TempoIndication) -> Element: - >>> mmod1.newReferent = 'longa' # music21 type w/ different musicxml name... + >>> mmod1.newReferent = 'longa' # music21 type w/ different musicxml name >>> mxDirection = MEX.tempoIndicationToXml(mmod1) >>> MEX.dump(mxDirection) @@ -6502,7 +6504,7 @@ def _matchesPreviousPartStaffInGroup( return comparison_wrapper(getattr(maybe_measure, attr)) # ----------------------------- - # note helpers... + # note helpers def lyricToXml(self, ly: note.Lyric): ''' @@ -6823,7 +6825,7 @@ def setMxAttributesObjectForStartOfMeasure(self): # TODO: footnote # TODO: level - # TODO: Do something more intelligent with this... + # TODO: Do something more intelligent with this self.currentDivisions = defaults.divisionsPerQuarter if self.parent is None or self.currentDivisions != self.parent.lastDivisions: @@ -7095,11 +7097,11 @@ def keySignatureToXml(self, keyOrKeySignature): seta(keyOrKeySignature, mxKey, 'mode', 'mode') else: - # choice... non-traditional-key... + # choice: non-traditional-key for p in keyOrKeySignature.alteredPitches: seta(p, mxKey, 'key-step', 'step') a = p.accidental - if a is None: # can't imagine why it would be... + if a is None: # can't imagine why it would be a = pitch.Accidental(0) mxAlter = SubElement(mxKey, 'key-alter') mxAlter.text = str(common.numToIntOrFloat(a.alter)) @@ -7257,7 +7259,7 @@ def setMxPrint(self): # note: this class match is a problem in cases where the object # is created in the module itself, as in a test. - # do a quick search for any layout objects before searching individually... + # do a quick search for any layout objects before searching individually foundAny = m.getElementsByClass(layout.LayoutBase) if not foundAny: return @@ -7314,7 +7316,7 @@ def setMxAttributes(self): sets the attributes (x=y) for a measure, that is, number, implicit, and layoutWidth - Does not create the tag. That's elsewhere... + Does not create the tag. That's elsewhere. ''' m = self.stream if hasattr(m, 'measureNumberWithSuffix'): diff --git a/music21/musicxml/testPrimitive.py b/music21/musicxml/testPrimitive.py index 7a110e4f18..d6ef8a3193 100644 --- a/music21/musicxml/testPrimitive.py +++ b/music21/musicxml/testPrimitive.py @@ -17673,7 +17673,7 @@ ''' -# Copyright string in the Creator name... +# Copyright string in the Creator name # noinspection SpellCheckingInspection unicodeStrWithNonAscii = ''' >> musicxml.xmlObjects.fractionToPercent(0.25) '25' - Only does whole numbers for now... + Only does whole numbers for now: >>> musicxml.xmlObjects.fractionToPercent(0.251) '25' diff --git a/music21/musicxml/xmlToM21.py b/music21/musicxml/xmlToM21.py index 711f541da2..a32f78b9d7 100644 --- a/music21/musicxml/xmlToM21.py +++ b/music21/musicxml/xmlToM21.py @@ -86,7 +86,7 @@ # ------------------------------------------------------------------------------ -# Helpers... +# Helpers def _clean(badStr: str|None) -> str|None: # need to remove badly-formed strings if badStr is None: @@ -166,7 +166,7 @@ def musicXMLTypeToType(value: str) -> str: def _floatOrIntStr(strObj): ''' - Convert a string to float or int if possible... + Convert a string to float or int if possible. >>> _f = musicxml.xmlToM21._floatOrIntStr >>> _f('20.3') @@ -330,7 +330,7 @@ def setStyleAttributes(self, mxObject, m21Object, musicXMLNames, m21Names=None): except (ValueError, TypeError): pass - # only create a style object if we get this far... + # only create a style object if we get this far if stObj is None: stObj = m21Object.style setattr(stObj, m21Name, mxValue) @@ -409,7 +409,7 @@ def setPrintStyle(self, mxObject, m21Object): def setColor(self, mxObject, m21Object): ''' - Sets m21Object.style.color to be the same as color... + Sets m21Object.style.color to be the same as color. ''' # we repeat 'color' rather than just letting setStyleAttributes # handle it, because otherwise it will run the expensive @@ -541,7 +541,7 @@ def setEditorial(self, mxObj, m21Obj): referenceAttribute = mxLevel.get('reference') if referenceAttribute == 'yes': c.isReference = True - # TODO: attr: level-display: bracket, parentheses... + # TODO: attr: level-display: bracket, parentheses # TODO: musicxml 4: type=start/stop/single -- does this apply to one note or # start applying from here on until stop is encountered. default: single @@ -837,7 +837,7 @@ def xmlRootToScore(self, mxScore, inputM21=None): partId = p.get('id') if partId is None: # pragma: no cover partId = list(self.mxScorePartDict.keys())[0] - # Lilypond Test Suite allows for parsing w/o a part ID for one part... + # Lilypond Test Suite allows for parsing w/o a part ID for one part try: mxScorePart = self.mxScorePartDict[partId] except KeyError: # pragma: no cover @@ -1368,7 +1368,7 @@ def creatorToContributor(self, >>> c.name 'Beethoven, Ludwig van' - Pass in a Contributor object and set it... + Pass in a Contributor object and set it: >>> c2 = metadata.Contributor() >>> MI.creatorToContributor(creator, c2) @@ -1470,7 +1470,7 @@ def __init__(self, self.lastClefs: dict[int, clef.Clef|None] = {NO_STAFF_ASSIGNED: clef.TrebleClef()} self.activeTuplets: list[duration.Tuplet|None] = [None] * 7 - self.maxStaves = 1 # will be changed in measure parsing... + self.maxStaves = 1 # will be changed in measure parsing self.lastMeasureNumber = 0 self.lastNumberSuffix: str|None = None @@ -1575,7 +1575,7 @@ def parseXmlScorePart(self): seta = _setAttributeFromTagText # TODO: musicxml 4: part-link: instrument-link, group-link - # put part info into the Part object and retrieve it later... + # put part info into the Part object and retrieve it later seta(part, mxScorePart, 'part-name', transform=_clean) mxPartName = mxScorePart.find('part-name') if mxPartName is not None: @@ -1583,7 +1583,7 @@ def parseXmlScorePart(self): if printObject == 'no': part.style.printPartName = False - # This will later be put in the default instrument object also also... + # This will later be put in the default instrument object also. # TODO: part-name-display seta(part, mxScorePart, 'part-abbreviation', transform=_clean) @@ -1592,7 +1592,7 @@ def parseXmlScorePart(self): printObject = mxPartAbbreviation.get('print-object') if printObject == 'no': part.style.printPartAbbreviation = False - # This will later be put in instrument.partAbbreviation also... + # This will later be put in instrument.partAbbreviation also # TODO: part-abbreviation-display # Q: is group covered elsewhere? @@ -1669,7 +1669,7 @@ def getDefaultInstrument(self, mxScorePart: ET.Element|None = None) -> instrumen def _adjustMidiData(mc): adjusted = int(mc) - 1 if adjusted == -1: - adjusted = 0 # a lot of zero indexed pianos... + adjusted = 0 # a lot of zero indexed pianos return adjusted seta = _setAttributeFromTagText @@ -1833,7 +1833,7 @@ def copy_into_partStaff(source: stream.Stream, sourceMeasureIterator = self.stream.getElementsByClass(stream.Measure) for staffIndex, staffKey in enumerate(uniqueStaffKeys): - # staffIndex should be staffKey - 1, but you never know... + # staffIndex should be staffKey - 1, but you never know removeClasses = STAFF_SPECIFIC_CLASSES[:] if staffIndex != 0: # spanners only on the first staff. removeClasses.append('Spanner') @@ -1980,7 +1980,7 @@ def xmlMeasureToMeasure(self, mxMeasure: ET.Element) -> stream.Measure: # TODO: move this into the measure parsing, # because it should happen on a voice level. if measureParser.fullMeasureRest is True: - # recurse is necessary because it could be in voices... + # recurse is necessary because it could be in voices r1 = m[note.Rest].first() if t.TYPE_CHECKING: @@ -2042,7 +2042,7 @@ def updateTransposition(self, newTransposition: interval.Interval): self.stream.coreInsert(self.lastMeasureOffset, newInst) else: # There is no activeInstrument and we're not at the beginning - # of the piece... this shouldn't happen, but let's send a warning + # of the piece. This shouldn't happen, but let's send a warning # and create a Generic Instrument object rather than dying. warnings.warn( 'Received a transposition tag, but no instrument to put it on!', @@ -2269,7 +2269,7 @@ def applyMultiMeasureRest(self, r: note.Rest): >>> pp.activeMultiMeasureRestSpanner is mmrSpanner True - >>> pp.stream.show('text') # Nothing... + >>> pp.stream.show('text') # Nothing shown! >>> r2 = note.Rest(type='whole', id='r2') >>> pp.applyMultiMeasureRest(r2) @@ -2341,7 +2341,7 @@ class MeasureParser(SoundTagMixin, XMLParserBase): 'grouping': None, 'link': None, 'bookmark': None, - # Note: is handled separately... + # Note: is handled separately # and xmlSound are found in xmlSoundParser.py } def __init__(self, @@ -2415,7 +2415,7 @@ def __init__(self, def getStaffNumber(mxObjectOrNumber) -> int: ''' gets an int representing a staff number, or 0 (representing no staff assigned) - from an mxObject or a number... + from an mxObject or a number: >>> mp = musicxml.xmlToM21.MeasureParser() >>> from xml.etree.ElementTree import fromstring as EL @@ -2426,18 +2426,18 @@ def getStaffNumber(mxObjectOrNumber) -> int: >>> gsn('2') 2 - tags store their staff numbers in a tag's text... + tags store their staff numbers in a tag's text: >>> gsn(EL('2')) 2 - ...or not at all. + Or if there is no tag, they get a special NO_STAFF_ASSIGNED value. >>> el = EL('C4') >>> gsn(el) == musicxml.xmlToM21.NO_STAFF_ASSIGNED True - Clefs, however, store theirs in a `number` attribute. + Clefs, however, store their staff numbers in a `number` attribute. >>> gsn(EL('')) 2 @@ -2675,7 +2675,7 @@ def hasSystemLayout(): sl = self.xmlPrintToSystemLayout(mxPrint) m.insert(0.0, sl) if addStaffLayout is True: - # assumes addStaffLayout is there... + # assumes addStaffLayout is there slFunc = self.xmlStaffLayoutToStaffLayout stlList = [slFunc(mx) for mx in mxPrint.iterfind('staff-layout')] # If bugs incorporate Ariza additional checks, but @@ -2736,7 +2736,7 @@ def xmlToNote(self, mxNote: ET.Element) -> None: isChord = True # do not count extra pitches in chord as note. - # it might be the first note of the chord... + # it might be the first note of the chord if nextNoteIsChord: isChord = True # first note of chord is not identified. voiceOfChord = mxNote.find('voice') @@ -2749,20 +2749,20 @@ def xmlToNote(self, mxNote: ET.Element) -> None: pass self.lastVoice = vIndex - if isChord is True: # and isRest is False...? + if isChord is True: # and isRest is False? n = None # for linting self.mxNoteList.append(mxNote) # store lyrics for latter processing for mxLyric in mxNote.findall('lyric'): self.mxLyricList.append(mxLyric) - elif isChord is False and isRest is False: # normal note... + elif isChord is False and isRest is False: # normal note self.restAndNoteCount['note'] += 1 n = self.xmlToSimpleNote(mxNote) else: # it's a rest self.restAndNoteCount['rest'] += 1 n = self.xmlToRest(mxNote) - if isChord is False: # normal note or rest... + if isChord is False: # normal note or rest if t.TYPE_CHECKING: assert isinstance(n, note.GeneralNote) @@ -2969,7 +2969,7 @@ def xmlToSimpleNote(self, mxNote, freeSpanners=True) -> note.Note|note.Unpitched if mxNotehead is not None: self.xmlNotehead(n, mxNotehead) - # after this, use combined function for notes and rests... + # after this, use combined function for notes and rests return self.xmlNoteToGeneralNoteHelper(n, mxNote, freeSpanners=freeSpanners) # beam and beams @@ -3292,7 +3292,7 @@ def xmlToAccidental( acc.set(name, allowNonStandardValue=True) self.setPrintStyle(mxAccidental, acc) - # level display... + # level display parentheses = mxAccidental.get('parentheses') bracket = mxAccidental.get('bracket') if parentheses == 'yes' and bracket == 'yes': @@ -3394,7 +3394,7 @@ def xmlToRest(self, mxRest): if isFullMeasure == 'yes': # fullMeasureRest is now just a counting/debug tool. if not (rType := strippedText(mxRest.find('type'))) or rType in ('whole', 'breve'): - # force full measure rest... + # force full measure rest self.fullMeasureRest = True r.fullMeasure = True # this attribute is not 100% necessary to get a multi-measure rest spanner @@ -3484,14 +3484,14 @@ def xmlNoteToGeneralNoteHelper(self, n, mxNote, freeSpanners=True): if mxNote.find('tie') is not None: n.tie = self.xmlToTie(mxNote) - # provide all because of tied... - # TODO: find tied if tie is not found... (cue notes) + # provide all because of tied + # TODO: find tied if tie is not found (cue notes) # translate if necessary, otherwise leaves unchanged if isGrace is True: n = self.xmlGraceToGrace(mxGrace, n) # this must be before notations, to get the slurs, etc. - # attached to the grace notes... + # attached to the grace notes mxNotations = mxNote.findall('notations') for mxN in mxNotations: @@ -4055,7 +4055,7 @@ def xmlOrnamentToExpression( orn = xmlObjects.ORNAMENT_MARKS[tag](delay=OrnamentDelay.NO_DELAY) else: orn = xmlObjects.ORNAMENT_MARKS[tag]() - except KeyError: # should already be checked... + except KeyError: # should already be checked return None self.setPrintStyle(mxObj, orn) # trill-sound? @@ -4264,7 +4264,7 @@ def xmlToTremolo(self, mxTremolo, n): or to a spanner, returning either. ''' # tremolo is tricky -- can be either an - # expression or spanner... + # expression or spanner tremoloType = mxTremolo.get('type') isSingle = True if tremoloType in ('start', 'stop'): @@ -4389,7 +4389,7 @@ def xmlToTie(self, mxNote): synchronizeIds(firstTied, tieObj) tieStyle = firstTied.get('line-type') - if tieStyle is not None and tieStyle != 'wavy': # do not support wavy... + if tieStyle is not None and tieStyle != 'wavy': # do not support wavy tieObj.style = tieStyle placement = firstTied.get('placement') if placement is not None: @@ -4465,7 +4465,7 @@ def xmlToTuplets(self, mxNote: ET.Element) -> list[duration.Tuplet]: returnTuplets: list[duration.Tuplet|None] = [None] * 8 removeFromActiveTuplets = set() - # a set of tuplets to set to stop... + # a set of tuplets to set to stop tupletsToStop = set() if mxNotations is not None: @@ -5092,7 +5092,7 @@ def xmlToChordSymbol( # TODO: print-style - if chordKind: # two ways of doing it... + if chordKind: # two ways of doing it if t.TYPE_CHECKING: assert mxKind is not None # Get m21 chord kind from dict of musicxml aliases ("dominant" -> "dominant-seventh") @@ -5111,8 +5111,8 @@ def xmlToChordSymbol( rootText = mxRS.text if rootText in (None, ''): - rootText = mxRS.get('text') # two ways to do it... this should do display even - # if content is supported. + rootText = mxRS.get('text') # two ways to do it + # this should do display even if content is supported. if rootText is not None: r = pitch.Pitch(rootText) mxRootAlter = mxRoot.find('root-alter') @@ -5172,7 +5172,7 @@ def xmlToChordSymbol( # TODO: frame if mxFrame is not None: pass - # TODO: Luke: Uncomment this next line when method is ready... + # TODO: Luke: Uncomment this next line when method is ready # self.xmlFrameToFretBoard(mxFrame, cs) return cs @@ -5559,7 +5559,7 @@ def xmlTransposeToInterval(self, mxTranspose): Not mentioned in MusicXML XSD but supported in (Finale; MuseScore): octave-change - refers to both diatonic and chromatic, so we will deal... + refers to both diatonic and chromatic, so we will deal: >>> t = ET.fromstring('-1-2' ... + '-1') @@ -5733,7 +5733,7 @@ def xmlToTimeSignature( ts.symbolizeDenominator = True elif symbol == 'dotted-note': pass - # TODO: support, but not as musicxml style -- reduces by 1/3 the numerator... + # TODO: support, but not as musicxml style -- reduces by 1/3 the numerator # this should be done by changing the displaySequence directly. return ts @@ -5809,7 +5809,7 @@ def xmlToClef(self, mxClef): # number is taken care of by insertCoreAndReference - # TODO: additional -- is this clef an additional clef to ignore... + # TODO: additional -- is this clef an additional clef to ignore # TODO: size # TODO: after-barline -- particular style to clef. self.setPrintStyle(mxClef, clefObj) @@ -5869,7 +5869,7 @@ def xmlToKeySignature(self, mxKey): try: ks = ks.asKey(modeValue) except exceptions21.Music21Exception: - pass # mxKeyMode might not be a valid mode -- in which case ignore... + pass # mxKeyMode might not be a valid mode -- in which case ignore self.mxKeyOctaves(mxKey, ks) self.setPrintStyle(mxKey, ks) self.setPrintObject(mxKey, ks) @@ -6187,7 +6187,7 @@ def parseMeasureNumbers(self, mNumRaw=None): m.numberSuffix = mSuffix # fix for Finale which calls unnumbered measures X1, X2, etc. which - # we convert to 1.X, 2.X, etc. without this... + # we convert to 1.X, 2.X, etc. without this if lastMNum is not None: if m.numberSuffix == 'X' and m.number != lastMNum + 1: newSuffix = m.numberSuffix + str(m.number) diff --git a/music21/note.py b/music21/note.py index d80697e398..6982928991 100644 --- a/music21/note.py +++ b/music21/note.py @@ -149,13 +149,14 @@ class Lyric(prebase.ProtoM21Object, style.StyleMixin): >>> l - Music21 processes leading and following hyphens intelligently... + Music21 processes leading and following hyphens intelligently by default. >>> l2 = note.Lyric(text='hel-') >>> l2 - ...unless applyRaw is set to True + If `applyRaw` is set to True then hyphens will be treated as actual text, + and the `syllabic` will be set to "single". >>> l3 = note.Lyric(number=3, text='hel-', applyRaw=True) >>> l3 @@ -848,7 +849,7 @@ def insertLyric(self, text, index=0, *, applyRaw=False, identifier=None): , ] - Test number as lyric... + Test number as lyric: >>> n1.insertLyric(0, 3) >>> n1.lyrics @@ -963,7 +964,8 @@ def getGrace(self, *, appoggiatura=False, inPlace=False): >>> ng.duration.components (DurationTuple(type='half', dots=0, quarterLength=0.0),) - Appoggiaturas are still a work in progress... + Appoggiaturas are still a work in progress. + * Changed in v6: corrected spelling of `appoggiatura` keyword. >>> ng2 = n.getGrace(appoggiatura=True) @@ -1740,7 +1742,7 @@ def transpose(self, value, *, inPlace=False): If the transposition value is an integer, take the KeySignature or Key context - into account... + into account >>> s = stream.Stream() >>> s.append(key.Key('D')) diff --git a/music21/noteworthy/binaryTranslate.py b/music21/noteworthy/binaryTranslate.py index 228fd2dd8d..29bd804277 100644 --- a/music21/noteworthy/binaryTranslate.py +++ b/music21/noteworthy/binaryTranslate.py @@ -863,7 +863,7 @@ def keySig(self): self.sharps = p.byteToInt() p.skipBytes(7) - # too complex... + # too complex # for letter in ['A', 'B', 'C', 'D', 'E', 'F', 'G']: # bitshift = ord(letter) - ord('A') # letterMask = 1 << bitshift @@ -1108,7 +1108,7 @@ def rest(self): p = self.parserParent self.type = 'Rest' if p.version <= 150: - print('igg...') + print('Does not work under version 1.50') else: self.duration = p.byteToInt() self.data2 = p.readBytes(5) diff --git a/music21/noteworthy/translate.py b/music21/noteworthy/translate.py index c412e5999a..10de21503b 100644 --- a/music21/noteworthy/translate.py +++ b/music21/noteworthy/translate.py @@ -30,14 +30,14 @@ # |Ending|Endings:1 # |Ending|Endings:2,D # -# ...as expression +# As expression # |TempoVariance|Style:Fermata|Pause:3|Pos:-4 # -# ...as spanner +# As spanner # |TempoVariance|Style:Accelerando|Pos:-6 # # -# ...beams: +# Beams: # |Note|Dur:8th|Pos:0|Opts:Stem=Down,Beam=First # |Note|Dur:8th|Pos:0|Opts:Stem=Down,Beam # |Note|Dur:8th|Pos:0|Opts:Stem=Down,Beam @@ -357,7 +357,7 @@ def getMultiplePitchesFromPositionInfo(self, posInfo): def getOnePitchFromPosition(self, pos): # noinspection PyShadowingNames ''' - get one pitch from a position... + Get one pitch from a position: >>> nwt = noteworthy.translate.NoteworthyTranslator() >>> nwt.currentClef = 'BASS' diff --git a/music21/omr/correctors.py b/music21/omr/correctors.py index 773f71dddd..84a9eec503 100644 --- a/music21/omr/correctors.py +++ b/music21/omr/correctors.py @@ -133,7 +133,7 @@ def getMeasureSlice(self, i): try: ms = self.measureSlices[i] if ms == 0: - raise IndexError('nope...') + raise IndexError(f'Measure slice {i} out of range') except IndexError: ms = MeasureSlice(self, i) if i >= len(self.measureSlices): diff --git a/music21/omr/evaluators.py b/music21/omr/evaluators.py index 2782781c6c..6778811f1e 100644 --- a/music21/omr/evaluators.py +++ b/music21/omr/evaluators.py @@ -90,7 +90,7 @@ def hashAll(self): def getOmrScore(self): ''' - Returns a ScoreCorrector object of the OMR score. does NOT store it anywhere... + Returns a ScoreCorrector object of the OMR score. does not store it anywhere >>> omrPath = omr.correctors.K525omrShortPath >>> ground = omr.correctors.K525groundTruthShortPath @@ -362,7 +362,7 @@ def autoCorrelationBestMeasure(inputScore): totalMeasures += 1 match = False - # horizontal search... + # horizontal search for j, nHash in enumerate(pHashArray): if i == j: continue @@ -370,7 +370,7 @@ def autoCorrelationBestMeasure(inputScore): match = True break - # vertical search... + # vertical search if match is False: for otherPNum in range(len(singleParts)): if otherPNum == pNum: diff --git a/music21/pitch.py b/music21/pitch.py index fcab6691e0..634edb7725 100644 --- a/music21/pitch.py +++ b/music21/pitch.py @@ -1015,7 +1015,7 @@ def __init__(self, specifier: int|str|float = 'natural'): self._name = '' self._modifier = '' self._alter = 0.0 # semitones to alter step - # potentially can be a fraction... but not exponent... + # potentially can be a fraction, but not exponent self.set(specifier) # SPECIAL METHODS # @@ -1941,7 +1941,7 @@ def __init__(self, # # CA, Q: should this remain an attribute or only refer to value in defaults? # # MSC A: no, it's a useful attribute for cases such as scales where if there are # # no octaves we give a defaultOctave higher than the previous - # # MSC 12 years later: maybe Chris was right... + # # MSC 12 years later: maybe Chris was right! # self.defaultOctave: int = defaults.pitchOctave # # MSC: even later: Chris Ariza was right self._octave: int|None = None @@ -2701,7 +2701,7 @@ def midi(self): >>> a.spellingIsInferred True - More absurd octaves... + More absurd octaves: >>> p = pitch.Pitch('c~4') >>> p.octave = -1 @@ -2821,7 +2821,7 @@ def name(self, usrStr: str): else: raise PitchException(f'Cannot make a name out of {usrStr!r}') - if octFoundStr: # bool('0') == True, so okay... + if octFoundStr: # bool('0') == True, so okay octave = int(octFoundStr) self.octave = octave @@ -3024,7 +3024,7 @@ def step(self, usrStr: StepName) -> None: def pitchClass(self) -> int: ''' Returns or sets the integer value for the pitch, 0-11, where C=0, - C#=1, D=2...B=11. Can be set using integers (0-11) or 'A' or 'B' + C#=1, D=2, etc. to B=11. Can be set using integers (0-11) or 'A' or 'B' for 10 or 11. >>> a = pitch.Pitch('a3') @@ -3242,7 +3242,7 @@ def german(self) -> str: >>> p1.german Traceback (most recent call last): music21.pitch.PitchException: - Es geht nicht "german" zu benutzen mit Microt...nen. Schade! + Es geht nicht "german" zu benutzen mit Microtönen. Schade! Note these rarely used pitches: @@ -3273,7 +3273,7 @@ def german(self) -> str: else: # flats if tempStep in ('C', 'D', 'F', 'G', 'H'): firstFlatName = 'es' - else: # A, E. Bs should never occur... + else: # A, E. Bs should never occur firstFlatName = 's' multipleFlats = abs(tempAlter) - 1 tempName = tempStep + firstFlatName + (multipleFlats * 'es') @@ -4012,7 +4012,7 @@ def isEnharmonic(self, other: Pitch) -> bool: # if pitch spaces are equal, these are enharmonics return other.ps == self.ps - # a cache so that interval objects can be reused... + # a cache so that interval objects can be reused _transpositionIntervals: dict[t.Literal['d2', '-d2'], interval.Interval] = {} @overload @@ -4113,7 +4113,7 @@ def getHigherEnharmonic(self: PitchType, *, inPlace: bool = False) -> PitchType| >>> print(pHalfSharp) E-4(-50c) ''' - # sigh...mypy + # sigh: mypy if inPlace: self._getEnharmonicHelper(inPlace=True, up=True) return None @@ -4155,7 +4155,7 @@ def getLowerEnharmonic(self: PitchType, *, inPlace: bool = False) -> PitchType|N >>> print(p1) B##2 ''' - # sigh...mypy + # sigh: mypy if inPlace: self._getEnharmonicHelper(inPlace=True, up=False) return None @@ -4390,7 +4390,7 @@ def getAllCommonEnharmonics(self: PitchType, alterLimit: int = 2) -> list[PitchT post: list[PitchType] = [] c = self.simplifyEnharmonic(inPlace=False) if c is None: # pragma: no follow - return post # not going to happen... + return post # not going to happen if c.name != self.name: post.append(c) @@ -4706,7 +4706,7 @@ def transposeBelowTarget( - This does nothing because it is already low enough... + This does nothing because it is already low enough: >>> pitch.Pitch('g#2').transposeBelowTarget(pitch.Pitch('f#8')) @@ -5060,7 +5060,7 @@ def set_displayStatus(newDisplayStatus: bool): set_displayStatus(True) return - # no pitches in the past list... + # no pitches in the past list if not pitchPastAll: # if we have no past, we show the accidental if this pitch name # is not in the alteredPitches list, or for naturals: if the @@ -5099,7 +5099,7 @@ def set_displayStatus(newDisplayStatus: bool): return else: # names are the same, skip this line of questioning break - # nope, no conflicting accidentals at this name and octave in the past... + # 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 @@ -5157,7 +5157,7 @@ def set_displayStatus(newDisplayStatus: bool): # of enormous measure of all same, leading to O(n^2) operation # but fine for the size of n we see. - # do we have a continuous stream of the same note leading up to this one... + # do we have a continuous stream of the same note leading up to this one if pitchPastAll[j].nameWithOctave != self.nameWithOctave: continuousRepeatsInMeasure = False break @@ -5338,7 +5338,7 @@ def set_displayStatus(newDisplayStatus: bool): setFromPitchPast = True break elif pPast.accidental.displayStatus is False: - # in case of ties... + # in case of ties displayAccidentalIfNoPreviousAccidentals = True else: if not self._nameInKeySignature(alteredPitches): diff --git a/music21/repeat.py b/music21/repeat.py index 8569f8c037..8843da337b 100644 --- a/music21/repeat.py +++ b/music21/repeat.py @@ -399,7 +399,7 @@ def __init__(self, text=None, **keywords): # ------------------------------------------------------------------------------ # store a list of one each of RepeatExpression objects; these are used for t # testing TextExpressions -# 500 microseconds to run... +# 500 microseconds to run repeatExpressionReference = [ Coda(), Segno(), Fine(), DaCapo(), DaCapoAlFine(), DaCapoAlCoda(), AlSegno(), DalSegno(), DalSegnoAlFine(), DalSegnoAlCoda(), @@ -1745,7 +1745,7 @@ def isExpandable(self) -> bool|None: if it has balanced repeats or sensible Da Capo or Dal Segno indications. - Return None if there's nothing to expand (a third case...) + Return None if there's nothing to expand (a third case). ''' match = self._daCapoOrSegno() # if neither repeats nor segno/capo, then not expandable diff --git a/music21/roman.py b/music21/roman.py index c810c98f93..061b4a5934 100644 --- a/music21/roman.py +++ b/music21/roman.py @@ -123,7 +123,7 @@ def _getKeyFromCache(keyStr: str) -> key.Key: } -# this is sort of a crock... :-) but it's very helpful. +# this is sort of a crock :-) but it's very helpful. functionalityScores: dict[str, int] = { 'I': 100, 'i': 90, @@ -321,7 +321,7 @@ def postFigureFromChordAndKey(chordObj, keyObj=None): Fails on German Augmented 6th chords in root position. Calls them half-diminished chords. - (This is in OMIT...) + (This is in OMIT_FROM_etc.) ''' if keyObj is None: keyObj = key.Key(chordObj.root()) @@ -1057,10 +1057,10 @@ def romanNumeralFromChord( # # - (This is in OMIT...) + (This is in OMIT_FROM_etc.) ''' - # use these when we know the key... don't we need to know the mode? + # use these when we know the key. (But don't we need to know the mode too?) aug6subs = { '#ivo6b3': 'It6', '#ivob64': 'It64', # minor only @@ -1073,7 +1073,7 @@ def romanNumeralFromChord( 'IIø7b5#3': 'Fr7', # in major 'IIø6#42': 'Fr42', # in minor 'IIøb6#42': 'Fr42', # in major - 'IIø65': 'Fr65', # in minor seems wrong... + 'IIø65': 'Fr65', # in minor seems wrong 'IIø65b3': 'Fr65', # in major '#ii64b3': 'Sw43', @@ -1109,7 +1109,7 @@ def romanNumeralFromChord( 'i6b5bb3': 'Sw65', 'io6b5b3': 'Ger65', - # Ger7 = iø7 -- is wrong... + # Ger7 = iø7 -- is wrong 'iob64b3': 'Ger43', 'iob6b42': 'Ger42', } @@ -1191,7 +1191,7 @@ def romanNumeralFromChord( if (not isMajorThird and inversionString in minorSeventhSubs - # only do expensive call in case it might be possible... + # only do expensive call in case it might be possible and chordObj.isSeventhOfType((0, 3, 7, 10))): rnString = ft.prefix + stepRoman + minorSeventhSubs[inversionString] elif (not isMajorThird @@ -1485,7 +1485,7 @@ class RomanNumeral(harmony.Harmony): >>> [str(p) for p in minorV.pitches] ['F#4', 'A4', 'B4', 'D5'] - (We will do this `str(p) for p in...` thing enough that let's make a helper function:) + (We will do this `str(p) for p in` thing enough that let's make a helper function:) >>> def cp(rn_in): # cp = chord pitches ... return [str(p) for p in rn_in.pitches] @@ -2611,7 +2611,7 @@ def _findSemitoneSizeForQuality(self, impliedQuality: str) -> tuple[int, ...]: >>> r._findSemitoneSizeForQuality('minor-seventh') (3, 7, 10) - (This is in OMIT...) + (This is in OMIT_FROM_etc.) ''' correctSemitones: tuple[int, ...] if impliedQuality == 'major': @@ -2720,7 +2720,7 @@ def shouldSkipThisChordStep(chordStep: int) -> bool: # special cases for chords whose 7th does not necessarily match the scale. if self.impliedQuality == 'minor' and self.semitonesFromChordStep(7) == 11: # i7 or iv7 chord or their inversions, in a major context. - # check first that this isn't on purpose... + # check first that this isn't on purpose if not shouldSkipThisChordStep(7): correctFaultyPitch(self.seventh, -1) @@ -2741,8 +2741,8 @@ def _correctForSecondaryRomanNumeral( If figure is None, uses newFigure. >>> k = key.Key('C') - >>> r = roman.RomanNumeral('I', k) # will not be used below... - >>> r._correctForSecondaryRomanNumeral(k) # uses 'I'. nothing should change... + >>> r = roman.RomanNumeral('I', k) # will not be used below + >>> r._correctForSecondaryRomanNumeral(k) # uses 'I'. nothing should change ('I', ) >>> r.secondaryRomanNumeral is None True @@ -2762,7 +2762,7 @@ def _correctForSecondaryRomanNumeral( >>> r.secondaryRomanNumeralKey - Recursive... + Recursive: >>> r._correctForSecondaryRomanNumeral(k, 'V7/V/V') ('V7', ) @@ -2801,7 +2801,7 @@ def _correctForSecondaryRomanNumeral( else: secondaryMode = 'major' - # TODO: this should use a KeyCache... + # TODO: this should use a KeyCache # but lower priority since secondaries are relatively rare self.secondaryRomanNumeralKey = key.Key( secondaryRomanNumeral.root().name, @@ -2924,7 +2924,7 @@ def _parseFrontAlterations(self, workingFigure: str) -> str: group = match.group() alteration = len(group) if group[0] in ('b', '-'): - alteration *= -1 # else sharp... + alteration *= -1 # else sharp frontAlterationTransposeInterval = interval.intervalFromGenericAndChromatic( interval.GenericInterval(1), interval.ChromaticInterval(alteration), @@ -3152,7 +3152,7 @@ def changeFrontAlteration(intV: interval.Interval, alter: int): if not self.caseMatters: return workingFigure - # THIS IS WHERE sixthMinor and seventhMinor goes... + # THIS IS WHERE sixthMinor and seventhMinor goes if self.scaleDegree == 6: minorDefault = self.sixthMinor else: @@ -3356,7 +3356,7 @@ def romanNumeral(self) -> str: Traceback (most recent call last): ValueError: Cannot set romanNumeral property of RomanNumeral objects - (This is in OMIT...) + (This is in OMIT_FROM_etc.) ''' if self.romanNumeralAlone in ('Ger', 'Sw', 'It', 'Fr'): return self.romanNumeralAlone @@ -3467,7 +3467,7 @@ def key(self, keyOrScale): existing figure. ''' if keyOrScale == self._scale and keyOrScale is not None: - return # skip... + return # skip # try to get Scale or Key object from cache: this will offer # performance boost as Scale stores cached pitch segments @@ -3482,7 +3482,7 @@ def key(self, keyOrScale): 'Cannot call classes on object {0!r}, send only Key ' 'or Scale Music21Objects'.format(keyOrScale)) if 'Key' in keyClasses: - # good to go... + # good to go if keyOrScale.tonicPitchNameWithCase not in _keyCache: # store for later _keyCache[keyOrScale.tonicPitchNameWithCase] = keyOrScale @@ -3654,7 +3654,7 @@ def functionalityScore(self) -> int: return self._functionalityScore if self.secondaryRomanNumeral: - figures = self.figure.split('/') # error for half-diminished in secondary... + figures = self.figure.split('/') # error for half-diminished in secondary score = 100.0 for f in figures: try: @@ -3877,7 +3877,7 @@ def isMixture(self, >>> roman.RomanNumeral('iv', 'C').key.mode 'major' - (This is in OMIT...) + (This is in OMIT_FROM_etc.) ''' if evaluateSecondaryNumeral and self.secondaryRomanNumeral: @@ -4320,7 +4320,7 @@ def test_augmented_round_trip(self): for aug6 in augTests: rn = RomanNumeral(aug6, c_minor) ch = chord.Chord(rn.pitches) - # without key... + # without key rn_out = romanNumeralFromChord(ch) if aug6 not in ('Ger7', 'Fr7'): # TODO(msc): fix these -- currently giving iø7 and Iø7 respectively @@ -4510,7 +4510,7 @@ def new_fig_equals_old_figure(rn_in, k='C'): rn3 = romanNumeralFromChord(ch3, 'g') self.assertEqual(rn3.figure, 'iv43[#7]') new_fig_equals_old_figure(rn3, 'g') - # except third-inversion... + # except third-inversion ch4 = chord.Chord('B4 C5 E-5 G5') rn4 = romanNumeralFromChord(ch4, 'g') self.assertEqual(rn4.figure, 'iv42[#7]') diff --git a/music21/romanText/clercqTemperley.py b/music21/romanText/clercqTemperley.py index 154422b07c..1e75b4ccd6 100644 --- a/music21/romanText/clercqTemperley.py +++ b/music21/romanText/clercqTemperley.py @@ -310,7 +310,7 @@ class CTSong(prebase.ProtoM21Object): OMIT_FROM_DOCS - one more example...the bane of this parser's existence...:: + one more example, which is the bane of this parser's existence:: % Ring Of Fire @@ -587,7 +587,7 @@ def homeKey(self): def toPart(self, labelRomanNumerals=True, labelSubsectionsOnScore=True) -> stream.Part: # noinspection PyShadowingNames ''' - creates a Part object out of a from CTSong...also creates CTRule objects in the process, + creates a Part object out of a from CTSong and also creates CTRule objects in the process, filling their .streamFromCTSong attribute with the corresponding smaller inner stream. Individual attributes of a rule are defined by the entire CTSong, such as meter and time signature, so creation of CTRule objects typically occurs @@ -759,7 +759,7 @@ def expandSimpleContent( m = stream.Measure() atoms = content.split() - # key/timeSig pass... + # key/timeSig pass regularAtoms: list[str] = [] for atom in atoms: if atom.startswith('['): diff --git a/music21/romanText/rtObjects.py b/music21/romanText/rtObjects.py index 0ae9fc2976..6f58ec7854 100644 --- a/music21/romanText/rtObjects.py +++ b/music21/romanText/rtObjects.py @@ -751,18 +751,17 @@ def getBeatFloatOrFrac(self): Fraction(11, 6) - Similarly 0.25 adds 1/4 of 1/DENOM... to get 21/12 or 7/4 or 1.75 + Similarly 0.25 adds 1/4 of 1/DENOM, to get 21/12 or 7/4 or 1.75: >>> RTB('b1.66.25').getBeatFloatOrFrac() 1.75 - And 0.75 adds 3/4 of 1/DENOM to get 23/12 + And 0.75 adds 3/4 of 1/DENOM to get 23/12: >>> RTB('b1.66.75').getBeatFloatOrFrac() Fraction(23, 12) - - A weird way of writing 'b1.5' + A weird way of writing 'b1.5': >>> RTB('b1.33.5').getBeatFloatOrFrac() 1.5 diff --git a/music21/romanText/translate.py b/music21/romanText/translate.py index 0408fe4ee0..7579b493bd 100644 --- a/music21/romanText/translate.py +++ b/music21/romanText/translate.py @@ -392,7 +392,7 @@ def translateTokens(self, tokens): fixPickupMeasure(p) p.makeBeams(inPlace=True) p.makeAccidentals(inPlace=True) - _addRepeatsFromRepeatEndings(p, self.repeatEndings) # 1st and second endings... + _addRepeatsFromRepeatEndings(p, self.repeatEndings) # 1st and second endings return p def translateOneLineToken(self, lineToken: rtObjects.RTTagged): @@ -407,7 +407,7 @@ def translateOneLineToken(self, lineToken: rtObjects.RTTagged): md = self.md # environLocal.printDebug(['token', t]) - # most common case first... + # most common case first if lineToken.isMeasure(): if t.TYPE_CHECKING: assert isinstance(lineToken, rtObjects.RTMeasure) @@ -846,7 +846,7 @@ def processRTChord(self, a, m, currentOffset): cacheTuple = (aSrc, self.kCurrent.tonicPitchNameWithCase) if USE_RN_CACHE and cacheTuple in _rnKeyCache: # pragma: no cover # print('Got a match: ' + str(cacheTuple)) - # Problems with Caches not picking up pivot chords... + # Problems with Caches not picking up pivot chords # Not faster, see below. rn = copy.deepcopy(_rnKeyCache[cacheTuple]) else: @@ -858,7 +858,7 @@ def processRTChord(self, a, m, currentOffset): ) rn.writeAsChord = True _rnKeyCache[cacheTuple] = rn - # surprisingly, not faster... and more dangerous + # surprisingly, not faster, and more dangerous # rn = roman.RomanNumeral(aSrc, kCurrent) # # SLOWEST!!! # rn = roman.RomanNumeral(aSrc, kCurrent.tonicPitchNameWithCase) @@ -875,7 +875,7 @@ def processRTChord(self, a, m, currentOffset): # ... 'from music21 import roman, key; import copy; # ... k = key.Key("c#")', number=1000) # 22.49 - # # key cache, does not help much... + # # key cache, does not help much # >>> t('copy.deepcopy(r)', 'from music21 import roman; import copy; # ... r = roman.RomanNumeral("IV", "c#")', number=1000) # 19.01 @@ -1066,7 +1066,7 @@ def _consolidateRepeatEndings(repeatEndings): def _addRepeatsFromRepeatEndings(s, repeatEndings): ''' - given a Stream and the repeatEndings dict, add repeats to the stream... + Given a Stream and the repeatEndings dict, add repeats to the stream. ''' consolidatedRepeats = _consolidateRepeatEndings(repeatEndings) for repeatEndingTuple in consolidatedRepeats: @@ -1591,7 +1591,7 @@ def testSetRTVersion(self): pt.translateTokens(rtHandler.tokens) self.assertEqual(pt.romanTextVersion, 2.5) - # gives warning, not raises... + # gives warning, not raises # src = '''RTVersion: XYZ # m1 C: I''' # rtf = rtObjects.RTFile() diff --git a/music21/romanText/tsvConverter.py b/music21/romanText/tsvConverter.py index b988443772..f5b9e8f4af 100644 --- a/music21/romanText/tsvConverter.py +++ b/music21/romanText/tsvConverter.py @@ -735,7 +735,7 @@ def prepStream(self) -> stream.Score: currentMeasureLength = newTS.barDuration.quarterLength previousMeasure = entry.measure - if repeatBracket is not None and m is not None: # m should always be not None... + if repeatBracket is not None and m is not None: # m should always be not None repeatBracket.addSpannedElements(m) s.append(p) diff --git a/music21/scale/__init__.py b/music21/scale/__init__.py index fb9c963700..ad20ef311a 100644 --- a/music21/scale/__init__.py +++ b/music21/scale/__init__.py @@ -162,7 +162,7 @@ def extractPitchList(other, comparisonAttribute='nameWithOctave', removeDuplicat Now we remove the F-4, D5, and A also because we are working with `comparisonAttribute=pitchClass`. - Note that we're using a Stream as `other` now... + Note that we're using a Stream as `other` now: >>> [str(p) for p in scale.Scale.extractPitchList(s, comparisonAttribute='pitchClass')] ['A4', 'D4', 'E4', 'D#4'] @@ -1426,7 +1426,7 @@ def abstract(self): * Changed in v6: changing `.abstract` is now allowed. ''' - # copy before returning? (No... too slow) + # copy before returning? (No, it is too slow) return self._abstract @abstract.setter @@ -1899,7 +1899,7 @@ def getScaleDegreeAndAccidentalFromPitch(self, alterDiff = pitchAlter - foundAlter if alterDiff == 0: - # should not happen... + # should not happen return (scaleStepNormal, None) else: alterAccidental = pitch.Accidental(alterDiff) @@ -2148,7 +2148,7 @@ def nextPitch( else: raise ScaleException('direction cannot be zero') else: # when direction is a string, use scalar of 1 - stepScalar = 1 # stepSize is still used... + stepScalar = 1 # stepSize is still used directionEnum = direction # pick reverse direction for neighbor @@ -3158,7 +3158,7 @@ class SieveScale(ConcreteScale): OMIT_FROM_DOCS - Test that an empty SieveScale can be created... + Test that an empty SieveScale can be created: >>> sc = scale.SieveScale() ''' diff --git a/music21/scale/scala/__init__.py b/music21/scale/scala/__init__.py index 0d416d1659..bba9ad5d3a 100644 --- a/music21/scale/scala/__init__.py +++ b/music21/scale/scala/__init__.py @@ -185,7 +185,9 @@ class ScalaData: >>> sf.open(fp) >>> sd = sf.read() - >>> print(sd.description) # converted to unicode... + ScaleFile descriptions are converted to unicode. + + >>> print(sd.description) 26-note choice system of Shohé Tanaka, Studien i.G.d. reinen Stimmung (1890) >>> sd.pitchCount 26 diff --git a/music21/search/base.py b/music21/search/base.py index b46e83d23a..265d5f7ff1 100644 --- a/music21/search/base.py +++ b/music21/search/base.py @@ -141,7 +141,7 @@ class StreamSearcher: Now let's configure the algorithms: >>> ss.algorithms - [<...StreamSearcher.wildcardAlgorithm...>] + [] Wildcard search is a default algorithm that lets you use wildcards. I suggest you leave it in place and add to the algorithms list. We can add the @@ -149,8 +149,8 @@ class StreamSearcher: >>> ss.algorithms.append(search.StreamSearcher.rhythmAlgorithm) >>> ss.algorithms - [<...StreamSearcher.wildcardAlgorithm...>, - <...StreamSearcher.rhythmAlgorithm...>] + [, + ] Now run it: diff --git a/music21/search/serial.py b/music21/search/serial.py index f5526573a9..e59d374f03 100644 --- a/music21/search/serial.py +++ b/music21/search/serial.py @@ -776,7 +776,7 @@ def searchRowsOnlyExclude(self, n, partNumber): else: self.chordList = chordList = [n] - # all unique.... + # all unique if len(chordList) == self.searchLength: self.activeChordList = chordList[:] self.addActiveChords(partNumber) @@ -1804,7 +1804,7 @@ class TransposedMultisetMatcher(SegmentMatcher): def checkSearchedAlready(self, multiset): ''' - searched already uses counters... + searched already uses counters. ''' searchSegmentCounter = {} for i in range(12): diff --git a/music21/sieve.py b/music21/sieve.py index d5f83f561b..f8066e0cd7 100644 --- a/music21/sieve.py +++ b/music21/sieve.py @@ -1289,7 +1289,7 @@ def _parseResidual(self, usrStr): try: # assume we have either an int (M), or a tuple (M,N) # better to remove the eval, but at least there are no globals or locals this way - # waste of two {} dicts -- could be cached, but not worth it for now... + # waste of two {} dicts -- could be cached, but not worth it for now args = literal_eval(usrStr) except (NameError, SyntaxError, TypeError): return None @@ -1681,7 +1681,7 @@ def segment( # this may raise an exception if mal-formed try: # better to remove the eval, but at least there are no globals or locals this way - # waste of two {} dicts -- could be cached, but not worth it for now... + # waste of two {} dicts -- could be cached, but not worth it for now seg = eval(evalStr, {'__builtins__': {'set': set}}, {}) # pylint: disable=eval-used # print('---: ' + evalStr) # print('xxx: ' + repr(seg)) diff --git a/music21/sites.py b/music21/sites.py index 59f5758d6c..6b24f00e5a 100644 --- a/music21/sites.py +++ b/music21/sites.py @@ -78,9 +78,14 @@ class SiteRef(common.SlottedObjectMixin, prebase.ProtoM21Object): >>> s.siteWeakref - If you turn sites.WEAKREF_ACTIVE to False then .siteWeakref just stores another reference to the site. Bad for memory. Good for debugging pickling. + + OMIT_FROM_DOCS + + Note that the ...Stream was needed after Python 3.13. + When 3.13 is the lowest version, replace ... with the + actual output. ''' # CLASS VARIABLES # @@ -166,7 +171,7 @@ def __setstate__(self, state): _NoneSiteRef = SiteRef() -_NoneSiteRef.globalSiteIndex = -2 # -1 is used elsewhere... +_NoneSiteRef.globalSiteIndex = -2 # -1 is used elsewhere _NoneSiteRef.siteIndex = -2 _singletonCounter = common.SingletonCounter() @@ -365,7 +370,7 @@ def add(self, obj, timeValue=None, idKey=None, classString=None): if updateNotAdd is True: siteRef = self.siteDict[idKey] - siteRef.isDead = False # in case it used to be a dead site... + siteRef.isDead = False # in case it used to be a dead site else: siteRef = SiteRef() @@ -423,7 +428,7 @@ def yieldSites(self, Note that priorityTarget is searched only on id -- this could be dangerous if the target has been garbage collected and the id is reused. Unlikely since you have to - pass in the priorityTarget itself, so therefore it still exists... + pass in the priorityTarget itself, so therefore it still exists. This can be much faster than .get in the case where the sought-for site is earlier in the list. diff --git a/music21/spanner.py b/music21/spanner.py index 140466f3f8..62dd2699af 100644 --- a/music21/spanner.py +++ b/music21/spanner.py @@ -584,7 +584,7 @@ def fill( >>> ott3 = spanner.Ottava(note.Note('D'), note.Note('E')) >>> ott3.fill() Traceback (most recent call last): - music21.spanner.SpannerException: ...requires a searchStream or getFirst().activeSite + music21.spanner.SpannerException: Spanner.fill() requires a searchStream or getFirst().activeSite ''' if not self.fillElementTypes: diff --git a/music21/stream/base.py b/music21/stream/base.py index cc8c7fb479..242118cf71 100644 --- a/music21/stream/base.py +++ b/music21/stream/base.py @@ -91,7 +91,7 @@ class StreamDeprecationWarning(UserWarning): # Do not subclass Deprecation warning, because these - # warnings need to be passed to users... + # warnings need to be passed to users pass @@ -335,7 +335,7 @@ def __init__(self, # # all elements in the stream need to be of this class. # self.restrictClass = restrictClass - # these should become part of style or something else... + # these should become part of style or something else self.definesExplicitSystemBreaks = False self.definesExplicitPageBreaks = False @@ -1157,7 +1157,7 @@ def clef(self) -> clef.Clef|None: {0.0} ''' clefList = self.getElementsByClass(clef.Clef).getElementsByOffset(0) - # casting to list added 20microseconds... + # casting to list added 20microseconds return clefList.first() @clef.setter @@ -1750,13 +1750,13 @@ def remove(self, # experimental if self._mutable is False: # pragma: no cover raise ImmutableStreamException('Cannot remove from an immutable stream') - # TODO: Next to clean up... a doozy -- filter out all the different options. + # TODO: Next to clean up: It's a doozy -- filter out all the different options. # TODO: Add an option to renumber measures # TODO: Shift offsets if recurse is True if shiftOffsets is True and recurse is True: # pragma: no cover raise StreamException( - 'Cannot do both shiftOffsets and recurse search at the same time...yet') + 'Cannot do both shiftOffsets and recurse search at the same time, yet') targetList: list[base.Music21Object] if not common.isListLike(targetOrList): @@ -1769,7 +1769,7 @@ def remove(self, try: targetList = list(sorted(targetOrList, key=self.elementOffset)) except sites.SitesException: - # will not be found if recursing, it's not such a big deal... + # will not be found if recursing, it's not such a big deal targetList = list(targetOrList) else: if t.TYPE_CHECKING: @@ -1792,11 +1792,11 @@ def remove(self, break except (StreamException, sites.SitesException): continue - # recursion matched or didn't or wasn't run. either way no need for rest... + # recursion matched or didn't or wasn't run. either way no need for rest continue # Anything that messes with ._elements or ._endElements should be in core.py - # TODO: move it... + # TODO: move it matchedEndElement = False baseElementCount = len(self._elements) matchOffset = 0.0 # to avoid possibility of undefined @@ -1897,7 +1897,7 @@ def _removeIteration(self, streamIterator): ai = streamIterator.activeInformation popDict[ai['iterSection']].append(ai['sectionIndex']) - # do not pop while iterating... + # do not pop while iterating for section in popDict: sectionList = getattr(self, section) # self._elements or self._endElements @@ -2067,7 +2067,7 @@ def _replaceSpannerBundleForDeepcopy(self, new): origin = e.derivation.origin if origin is None: # pragma: no cover - continue # should not happen... + continue # should not happen if origin.sites.hasSpannerSite(): # environLocal.printDebug(['Stream.__deepcopy__', 'replacing component to', e]) @@ -2187,7 +2187,7 @@ def elementOffset(self, element, returnSpecial=False): try: # 2.3 million times found in TestStream o = self._offsetDict[id(element)][0] - # if returnedElement is not element: # stale reference... + # if returnedElement is not element: # stale reference # o = None # 0 in TestStream -- not worth testing except KeyError: # 445k - 442,443 = 3k in TestStream for idElement in self._offsetDict: # slower search @@ -2270,13 +2270,13 @@ def insert(self, >>> len(st3) 2 - Raises an error if offset is not a number + Raises an error if offset is not a number: >>> stream.Stream().insert('l', note.Note('B')) Traceback (most recent call last): music21.exceptions21.StreamException: Offset 'l' must be a number. - ...or if the object is not a music21 object (or a list of them) + Also raises an error if the object is not a music21 object (or a list of them) >>> stream.Stream().insert(3.3, 'hello') Traceback (most recent call last): @@ -2375,7 +2375,7 @@ def insertIntoNoteOrChord(self, offset, noteOrChord, chordsOnly=False): Notice that the duration of the inserted element is not taken into consideration and the original element is not broken up, - as it would be in chordify(). But Chords and Notes are created... + as it would be in chordify(). But Chords and Notes are created: >>> for i in [0.0, 2.0, 4.0]: ... s.insertIntoNoteOrChord(i, note.Note('F#4')) @@ -2384,7 +2384,7 @@ def insertIntoNoteOrChord(self, offset, noteOrChord, chordsOnly=False): {2.0} {4.0} - if chordsOnly is set to True then no notes are returned, only chords, but + If chordsOnly is set to True then no notes are returned, only chords, but untouched notes are left alone: >>> s2.insert(5.0, note.Note('E##4')) @@ -2468,7 +2468,7 @@ def insertIntoNoteOrChord(self, offset, noteOrChord, chordsOnly=False): removeTarget = None # environLocal.printDebug(['insertIntoNoteOrChord', [e for e in targets]]) if len(targets) == 1: - pitches = [] # avoid an undefined variable warning... + pitches = [] # avoid an undefined variable warning components = [] # ditto target = targets[0] # assume first @@ -3667,20 +3667,19 @@ def getElementsByClass(self, >>> totalFound 25 - The class name of the Stream created is the same as the original: + The class name of the Stream created is usually the same as the original: >>> found = a.getElementsByClass(note.Note).stream() >>> found.__class__.__name__ 'Score' - ...except if `returnStreamSubClass` is False, which makes the method + An exception is if `returnStreamSubClass` is False, which makes the method return a generic Stream: >>> found = a.getElementsByClass(note.Rest).stream(returnStreamSubClass=False) >>> found.__class__.__name__ 'Stream' - Make a list from a StreamIterator: >>> foundList = list(a.recurse().getElementsByClass(note.Rest)) @@ -4137,7 +4136,7 @@ def getElementAtOrBefore( # NOTE: this is a performance critical method # TODO: switch to trees if more than a certain number of elements. - # TODO: allow sortTuple as a parameter (in all getElement...) + # TODO: allow sortTuple as a parameter (in all getElementBy/At routines) candidates = [] offset: OffsetQL = opFrac(offset) @@ -4354,7 +4353,7 @@ def hasMeasureNumberInformation(measureIterator: iterator.StreamIterator[Measure mStreamIter: iterator.StreamIterator[Measure] = self.getElementsByClass(Measure) # FIND THE CORRECT ORIGINAL MEASURE OBJECTS - # for indicesNotNumbers, this is simple... + # for indicesNotNumbers, this is simple if indicesNotNumbers: if not isinstance(numberStart, int) or not isinstance(numberEnd, (int, types.NoneType)): raise ValueError( @@ -4365,7 +4364,7 @@ def hasMeasureNumberInformation(measureIterator: iterator.StreamIterator[Measure hasUniqueMeasureNumbers = hasMeasureNumberInformation(mStreamIter) - # unused... + # unused # originalNumberStart = numberStart # originalNumberEnd = numberEnd startSuffix = None @@ -4615,7 +4614,7 @@ def measures( startOffset: OffsetQL if not matches: startMeasure = None - startOffset = 0.0 # does not matter; could be any number... + startOffset = 0.0 # does not matter; could be any number else: startMeasure = matches[0] startOffset = startMeasure.getOffsetBySite(srcObj) @@ -5052,7 +5051,7 @@ def measureOffsetMap( # are returned first maybe_m = e.getContextByClass(Measure) # , sortByCreationTime='reverse') if maybe_m is None: # pragma: no cover - # hard to think of a time this would happen...But... + # hard to think of a time this would happen, but better safe. continue m = maybe_m # assuming that the offset returns the proper offset context @@ -5932,7 +5931,7 @@ def shiftElements(self, offset, startOffset=None, endOffset=None, classFilterLis {6.0} {7.0} - Now make the first note a dotted whole note and shift the rest by two quarters... + Now make the first note a dotted whole note and shift the rest by two quarters: >>> firstNote = st2[0] >>> firstNoteOldQL = firstNote.quarterLength @@ -6170,7 +6169,7 @@ def _uniqueOffsetsAndEndTimes(self, offsetsOnly=False, endTimesOnly=False): >>> [str(o) for o in s.flatten()._uniqueOffsetsAndEndTimes(endTimesOnly=True)] ['103/25', '5.0', '63/10', '6.5'] - And this is useless... :-) + And this is useless :-) >>> s.flatten()._uniqueOffsetsAndEndTimes(offsetsOnly=True, endTimesOnly=True) [] @@ -7288,7 +7287,7 @@ def stripTies( if returnObj.hasPartLikeStreams(): # part-like does not necessarily mean that the next level down is a stream.Part # object or that this is a stream.Score object, so do not substitute - # returnObj.parts for this... + # returnObj.parts for this for p in returnObj.getElementsByClass(Stream): # already copied if necessary; edit in place p.stripTies(inPlace=True, matchByPitch=matchByPitch) @@ -7786,7 +7785,7 @@ def flatten(self: StreamType, retainContainers=False) -> StreamType: >>> sc.getElementById('part2').elements (, ) - ...but if we want to get all the notes, storing their + If, however, we want to get all the notes, storing their offsets related to the beginning of the containing stream, one way is via calling .flatten() on sc and looking at the elements @@ -8165,7 +8164,7 @@ def recurse(self, Then the last offset/activeSite will be used. It's a bit of a speedup, but leads to some bad code, so use it only in highly optimized situations. - We'll also test using multiple classes here... the Stream given is the same as the + We'll also test using multiple classes here. The Stream given is the same as the s.flatten().notes stream. >>> for el in s.recurse(classFilter=('Note', 'Rest'), restoreActiveSites=False): @@ -8410,7 +8409,7 @@ def highestTime(self): # TODO(msc) -- why is cache 'HighestTime' and not 'highestTime'? # environLocal.printDebug(['_getHighestTime', 'isSorted', self.isSorted, self]) - # remove cache -- durations might change... + # remove cache -- durations might change if 'HighestTime' in self._cache and self._cache['HighestTime'] is not None: pass # return cache unaltered elif not self._elements: @@ -8993,7 +8992,7 @@ def beatAndMeasureFromOffset(self, searchOffset, fixZeros=True): raise StreamException( 'beatAndMeasureFromOffset: offset is beyond the end of the piece') foundMeasureNumber = myMeas.number - # deal with second half of partial measures... + # deal with second half of partial measures # Now we deal with the problem case, where we have the second half of a partial measure. # These are @@ -9351,14 +9350,14 @@ def quantize( [0.5, 0.5, 0.5, 0.25, 0.25] The error in quantization is set in the editorial attribute for the note in - two places `.offsetQuantizationError` and `.quarterLengthQuantizationError` + two places `.offsetQuantizationError` and `.quarterLengthQuantizationError`: >>> [e.editorial.offsetQuantizationError for e in s.notes] [0.1, -0.01, -0.1, -0.01, 0.01] >>> [e.editorial.quarterLengthQuantizationError for e in s.notes] [-0.01, -0.01, -0.01, 0.01, 0.01] - with default quarterLengthDivisors... + With default quarterLengthDivisors: >>> s = stream.Stream() >>> s.repeatInsert(n, [0.1, 0.49, 0.9]) @@ -9407,7 +9406,7 @@ def quantize( OMIT_FROM_DOCS - Test changing defaults, running, and changing back... + Test changing defaults, running, and changing back: >>> dd = defaults.quantizationQuarterLengthDivisors >>> defaults.quantizationQuarterLengthDivisors = (3,) @@ -9922,7 +9921,7 @@ def hasPartLikeStreams(self): False - A stream with a single generic Stream substream at the beginning has part-like Streams... + A stream with a single generic Stream substream at the beginning has part-like Streams: >>> s = stream.Score() >>> m1 = stream.Stream() @@ -10383,7 +10382,7 @@ def findConsecutiveNotes( continue returnList.append(e) - if e.offset < lastEnd: # is an overlap... + if e.offset < lastEnd: # is an overlap continue lastStart = e.offset @@ -10405,7 +10404,7 @@ def findConsecutiveNotes( ) and (getOverlaps is True or e.offset >= lastEnd)): returnList.append(e) - if e.offset < lastEnd: # is an overlap... + if e.offset < lastEnd: # is an overlap continue lastStart = e.offset @@ -10926,7 +10925,7 @@ def attachIntervalsBetweenStreams(self, cmpStream): >>> s1.attachIntervalsBetweenStreams(s2) >>> for n in s1.notes: ... if n.editorial.harmonicInterval is None: - ... print('None') # if other voice had a rest... + ... print('None') # Wil print if other voice had a rest. ... else: ... print(n.editorial.harmonicInterval.directedName) P12 @@ -10988,7 +10987,7 @@ def attachMelodicIntervals(self): >>> s.attachMelodicIntervals() >>> for n in s.notes: ... if n.editorial.melodicInterval is None: - ... print('None') # if other voice had a rest... + ... print('None') # Will print if other voice had a rest. ... else: ... print(n.editorial.melodicInterval.directedName) None @@ -13109,7 +13108,7 @@ def mergeAttributes(self, other): >>> m2 - Try with not another Measure... + Try with not another Measure: >>> m3 = stream.Stream() >>> m3.id = 'hello' @@ -13151,7 +13150,7 @@ def makeNotation(self, # TODO: this probably needs to look to see what processes need to be done; # for example, existing beaming may be destroyed. - # do this before deepcopy... + # do this before deepcopy # assuming we are not trying to get context of previous measure if not inPlace: # make a copy @@ -13491,7 +13490,7 @@ def _setLeftBarline(self, barlineObj): ''') def _getRightBarline(self): - # TODO: Move to Stream or make setting .rightBarline, etc. on Stream raise an exception... + # TODO: Move to Stream or make setting .rightBarline, etc. on Stream raise an exception # look on _endElements barList = [] for e in self._endElements: @@ -13559,7 +13558,7 @@ def _setRightBarline(self, barlineObj): OMIT_FROM_DOCS .measure currently isn't the same as the - original measure... + original measure. ''') @@ -13956,7 +13955,7 @@ def measure(self, Note that we still do a .getElementsByClass(chord.Chord) since many pieces end - with nothing but a rest... + with nothing but a rest. ''' if measureNumber < 0: indicesNotNumbers = True @@ -14323,7 +14322,7 @@ def makeNotation( # note: while the local-streams have updated their caches, the # containing score has an out-of-date cache of flat. # thus, must call elements changed - # but... since all we have done in this method is call coreGatherMissingSpanners() + # but, since all we have done in this method is call coreGatherMissingSpanners() # and makeNotation(), neither of which are supposed to leave the stream # unusable (with an out-of-date cache), the original issue was likely deeper # no matter, let's just be extra cautious and run this here (Feb 2021 - JTW) diff --git a/music21/stream/core.py b/music21/stream/core.py index 9bc3d059f8..125babeae9 100644 --- a/music21/stream/core.py +++ b/music21/stream/core.py @@ -66,7 +66,7 @@ def __init__(self, **keywords) -> None: # should isFlat become readonly? self.isFlat = True # does it have no embedded Streams - # someday... + # someday # self._elementTree = tree.trees.ElementTree(source=self) def coreInsert( @@ -256,7 +256,7 @@ def coreElementsChanged( # WHY??? THIS SEEMS OVERKILL, esp. since the first call to .sort() in .flatten() will # invalidate it! TODO: Investigate if this is necessary and then remove if not necessary - # should not need to do this... + # should not need to do this # if this Stream is a flat representation of something, and its # elements have changed, than we must clear the cache of that @@ -429,7 +429,7 @@ def coreGuardBeforeAddElement(self, element, *, checkRedundancy=True): f'the object ({element!r}, id()={id(element)} ' + f'is already found in this Stream ({self!r}, id()={id(self)})' ) - # something was old... delete from _offsetDict + # something was old. delete from _offsetDict # environLocal.warn('stale object') del self._offsetDict[idElement] # pragma: no cover # if we do not purge locations here, we may have ids() for diff --git a/music21/stream/filters.py b/music21/stream/filters.py index ba9d19effb..fdfce4f00a 100644 --- a/music21/stream/filters.py +++ b/music21/stream/filters.py @@ -157,7 +157,7 @@ class IsNotFilter(IsFilter): - test that resetting works... + test that resetting works: >>> for el in s.iter().addFilter(stream.filters.IsNotFilter(n)): ... el @@ -165,7 +165,7 @@ class IsNotFilter(IsFilter): - multiple... + Using multiple filters: >>> s = stream.Stream() >>> s.insert(0, key.KeySignature(-3)) @@ -415,7 +415,7 @@ def isElementOffsetInRange(self, e, offset, *, stopAfterEnd=False) -> bool: if offset > self.offsetEnd: # anything that begins after the span is definitely out if stopAfterEnd: # if sorted, optimize by breaking after exceeding offsetEnd - # eventually we could do a binary search to speed up... + # eventually we could do a binary search to speed up raise StopIteration return False diff --git a/music21/stream/iterator.py b/music21/stream/iterator.py index 3991982fe7..636cde4713 100644 --- a/music21/stream/iterator.py +++ b/music21/stream/iterator.py @@ -140,7 +140,7 @@ def __init__(self, self.srcStream: StreamType = srcStream self.elementIndex: int = 0 - # use .elements instead of ._elements/etc. so that it is sorted... + # use .elements instead of ._elements/etc. so that it is sorted self.srcStreamElements = t.cast(tuple[M21ObjType, ...], srcStream.elements) self.streamLength: int = len(self.srcStreamElements) @@ -169,7 +169,7 @@ def __init__(self, self._len: int|None = None self._matchingElements: dict[bool|None, list[M21ObjType]] = {} # keep track of where we are in the parse. - # esp important for recursive streams... + # esp important for recursive streams if activeInformation is not None: self.activeInformation: ActiveInformation = activeInformation else: @@ -776,7 +776,7 @@ def matchesFilters(self, e: base.Music21Object) -> bool: if f(e) is False: return False except StopIteration: # pylint: disable=try-except-raise - raise # clearer this way to see that this can happen... + raise # clearer this way to see that this can happen return True def _newBaseStream(self) -> stream.Stream: @@ -908,9 +908,9 @@ def stream(self, returnStreamSubClass=True) -> stream.Stream|StreamType: o = ss.elementOffset(e, returnSpecial=True) except SitesException: # this can happen in the case of, s.recurse().notes.stream() -- need to do new - # stream... + # stream o = e.getOffsetInHierarchy(ss) - clearIsSorted = True # now the stream is probably not sorted... + clearIsSorted = True # now the stream is probably not sorted if not isinstance(o, str): found.coreInsert(o, e, ignoreSort=True) @@ -918,7 +918,7 @@ def stream(self, returnStreamSubClass=True) -> stream.Stream|StreamType: if o == OffsetSpecial.AT_END: found.coreStoreAtEnd(e) else: - # TODO: something different... + # TODO: something different found.coreStoreAtEnd(e) if fe: @@ -1079,7 +1079,7 @@ def getElementsByClass( - ActiveSite is restored... + ActiveSite is restored. >>> s2 = stream.Stream(id='s2') >>> s2.insert(0, r) @@ -1475,14 +1475,14 @@ def getElementsByOffset( ) # ------------------------------------------------------------ - # properties -- historical... + # properties -- historical @property def notes(self): ''' Returns all :class:`~music21.note.NotRest` objects - (will sometime become simply Note and Chord objects...) + (will sometime become simply Note and Chord objects.) >>> s = stream.Stream() >>> s.append(note.Note('C')) @@ -1512,7 +1512,7 @@ def notesAndRests(self): - chained filters... (this makes no sense since notes is a subset of notesAndRests) + Chained filters (this makes no sense since notes is a subset of notesAndRests): >>> for el in s.iter().notesAndRests.notes: ... print(el) @@ -1614,7 +1614,7 @@ def __next__(self) -> list[M21ObjType]: # type: ignore raise StopIteration retElementList: list[M21ObjType] = [] - # make sure that cleanup is not called during the loop... + # make sure that cleanup is not called during the loop try: if self.nextToYield: retElementList = self.nextToYield @@ -1866,7 +1866,7 @@ def __next__(self) -> M21ObjType: childRecursiveIterator: RecursiveIterator[M21ObjType] = RecursiveIterator( srcStream=e, restoreActiveSites=self.restoreActiveSites, - filterList=self.filters, # shared list... + filterList=self.filters, # shared list activeInformation=self.activeInformation, # shared dict includeSelf=False, # always for inner streams ignoreSorting=self.ignoreSorting, @@ -1895,7 +1895,7 @@ def __next__(self) -> M21ObjType: # self.childRecursiveIterator.parentIterator = None self.childRecursiveIterator = None - self.activeInformation['lastYielded'] = None # always clean this up, no matter what... + self.activeInformation['lastYielded'] = None # always clean this up, no matter what self.cleanup() raise StopIteration diff --git a/music21/stream/makeNotation.py b/music21/stream/makeNotation.py index f9dc2a4ac7..43e6d97fd1 100644 --- a/music21/stream/makeNotation.py +++ b/music21/stream/makeNotation.py @@ -757,7 +757,7 @@ def makeRests( >>> a.show('text') {20.0} - Now make some rests... + Now make some rests: >>> b = a.makeRests(inPlace=False) >>> len(b) @@ -770,7 +770,7 @@ def makeRests( >>> b[0].duration.quarterLength 20.0 - Same thing, but this time, with gaps, and hidden rests... + Same thing, but this time, with gaps, and hidden rests: >>> a = stream.Stream() >>> a.insert(20, note.Note('C4')) @@ -1213,7 +1213,7 @@ def makeTies( if returnObj.hasPartLikeStreams(): # part-like does not necessarily mean that the next level down is a stream.Part # object or that this is a stream.Score object, so do not substitute - # returnObj.parts for this... + # returnObj.parts for this for p in returnObj.getElementsByClass(stream.Stream): # already copied if necessary; edit in place p.makeTies(meterStream=meterStream, @@ -1393,7 +1393,7 @@ def makeTupletBrackets(s: StreamType, *, inPlace=False) -> StreamType|None: ''' durationList: list[duration.Duration] = [] - # Stream, as it should be... + # Stream, as it should be if not inPlace: # make a copy returnObj = s.coreCopyAsDerivation('makeTupletBrackets') else: @@ -1466,7 +1466,7 @@ def makeTupletBrackets(s: StreamType, *, inPlace=False) -> StreamType|None: # this, below, is optional: # if next normal type is not the same as this one, also stop elif tupletNext is None or completionCount >= completionTarget: - tupletObj.type = 'stop' # should be impossible once frozen... + tupletObj.type = 'stop' # should be impossible once frozen completionTarget = None # reset completionCount = 0.0 # reset # environLocal.printDebug(['stopping tuplet type, value:', diff --git a/music21/stream/tests.py b/music21/stream/tests.py index db66dc817a..506b25c7e9 100644 --- a/music21/stream/tests.py +++ b/music21/stream/tests.py @@ -1976,7 +1976,7 @@ def testContextNestedB(self): post = sInnerFlat.getContextByClass(clef.Clef) self.assertIsInstance(post, clef.AltoClef) - # 2014 April -- tree version -- not needed... + # 2014 April -- tree version -- not needed # this will only work if the callerFirst is manually set to sInnerFlat # otherwise, this interprets the DefinedContext object as the first # caller @@ -2108,7 +2108,7 @@ def testContextNestedD(self): self.assertIsInstance(s1Measures[0].clef, clef.AltoClef) # this used to be False, then True, and the tiniest change to makeMeasures made it False - # again. I think it's better as "False" now... + # again. I think it's better as "False" now # self.assertIsInstance(s1Measures[0].clef, clef.TrebleClef) s2Measures = s2.makeMeasures() @@ -2851,7 +2851,7 @@ def testMakeAccidentalsTies(self): dsi, f'{i} failed, {thisNote.pitch.accidental.displayStatus} != {dsi}') - # add another B-flat just after the tied one... + # add another B-flat just after the tied one bm = converter.parse( "tinynotation: 4/4 c#'2 b-2~ b-8 b-8 c#'8~ c#'8 b-8 c#'8 b-8~ b-8~ b-8", makeNotation=False) @@ -4902,9 +4902,7 @@ def testMakeChordsBuiltD(self): def testGetElementAtOrBeforeBarline(self): ''' - problems with getting elements at or before - - when triplets are involved... + problems with getting elements at or before when triplets were involved. ''' bugtestFile = common.getSourceFilePath() / 'stream' / 'tripletOffsetBugtest.xml' s = converter.parse(bugtestFile) @@ -5032,7 +5030,7 @@ def testStoreAtEndFailures(self): with self.assertRaises(StreamException): s.storeAtEnd(n) - # also test that lists work... + # also test that lists work b = bar.Barline() s.storeAtEnd([b]) @@ -6704,7 +6702,7 @@ def testFlatCachingB(self): # environLocal.printDebug(['calling makeMeasures']) sPartFlat = sPart.flatten() unused_notesAndRests = sPartFlat.notesAndRests - # test cache... + # test cache sMeasures = sPart.flatten().notesAndRests.stream().makeMeasures(ts) target = [] for n in sMeasures.flatten().notesAndRests: @@ -7137,7 +7135,7 @@ def testSecondsMapB(self): s.insert([0, tempo.MetronomeMark(number=60)]) sMap = s._getSecondsMap() - sMapStr = '[' # construct string from dict in fixed order... + sMapStr = '[' # construct string from dict in fixed order for ob in sMap: sMapStr += ("{'durationSeconds': " + str(ob['durationSeconds']) + ", 'voiceIndex': " + str(ob['voiceIndex']) @@ -7164,7 +7162,7 @@ def testSecondsMapB(self): s.insert([0, tempo.MetronomeMark(number=15)]) sMap = s._getSecondsMap() - sMapStr = '[' # construct string from dict in fixed order... + sMapStr = '[' # construct string from dict in fixed order for ob in sMap: sMapStr += ("{'durationSeconds': " + str(ob['durationSeconds']) + ", 'voiceIndex': " + str(ob['voiceIndex']) @@ -7192,7 +7190,7 @@ def testSecondsMapB(self): 1, tempo.MetronomeMark(number=60)]) sMap = s._getSecondsMap() - sMapStr = '[' # construct string from dict in fixed order... + sMapStr = '[' # construct string from dict in fixed order # TODO: use OrderedDict. for ob in sMap: sMapStr += ("{'durationSeconds': " + str(ob['durationSeconds']) + ", 'voiceIndex': " + str(ob['voiceIndex']) @@ -7223,7 +7221,7 @@ def testSecondsMapB(self): 1, tempo.MetronomeMark(number=60)]) sMap = s._getSecondsMap() - sMapStr = '[' # construct string from dict in fixed order... + sMapStr = '[' # construct string from dict in fixed order # TODO: use OrderedDict. for ob in sMap: sMapStr += ("{'durationSeconds': " + str(ob['durationSeconds']) + ", 'voiceIndex': " + str(ob['voiceIndex']) @@ -7812,7 +7810,7 @@ def testChordifyF(self): # chords.show() GEX = m21ToXml.GeneralObjectExporter() raw = GEX.parse(m1).decode('utf-8') - # there should only be 2 tuplet indications in the produced chords: start and stop... + # there should only be 2 tuplet indications in the produced chords: start and stop self.assertEqual(raw.count(' maxTimeout and eventsProcessed > 0: - print('\nToo many delays, giving up...', flush=True) + print('\nToo many delays, giving up.', flush=True) continueIt = False printSummary(summaryOutput, timeStart, pathsToRun) pool.close() diff --git a/music21/test/testLint.py b/music21/test/testLint.py index 9f55a060ec..69208eab07 100644 --- a/music21/test/testLint.py +++ b/music21/test/testLint.py @@ -64,14 +64,14 @@ def main(fnAccept=None, strict=False): # 'demos/', # 'test/timeGraphs.py', '/ext/', - # 'bar.py', # used to crash pylint... - # 'repeat.py', # used to hang pylint... - # 'spanner.py', # used to hang pylint... + # 'bar.py', # used to crash pylint + # 'repeat.py', # used to hang pylint + # 'spanner.py', # used to hang pylint ] disable_unless_strict = [ 'too-many-statements', # someday - 'too-many-arguments', # definitely! but takes too long to get a fix now... + 'too-many-arguments', # definitely! but takes too long to get a fix now 'too-many-public-methods', # maybe, look 'too-many-branches', # yes, someday 'too-many-lines', # yes, someday. @@ -80,7 +80,7 @@ def main(fnAccept=None, strict=False): 'too-many-positional-arguments', # let's get this at least to max 6. 'inconsistent-return-statements', # would be nice 'protected-access', # this is an important one, but for now we do a lot of - # x = copy.deepcopy(self); x._volume = ... which is not a problem... + # x = copy.deepcopy(self); x._volume = ... which is not a problem # also, test suites need to be exempt. 'keyword-arg-before-vararg', # a good thing to check for new code, but # requires rewriting function signatures in old code @@ -91,28 +91,28 @@ def main(fnAccept=None, strict=False): # as initial ones are the same. 'arguments-renamed', # not an issue - 'multiple-imports', # import os, sys -- fine... + 'multiple-imports', # import os, sys -- fine 'redefined-variable-type', # would be good, but currently # lines like: if x: y = note.Note() ; else: y = note.Rest() # triggers this, even though y doesn't change. 'no-else-return', # these are unnecessary but can help show the flow of thinking. 'cyclic-import', # we use these inside functions when there's a deep problem. - 'unnecessary-pass', # nice, but not really a problem... + 'unnecessary-pass', # nice, but not really a problem 'locally-disabled', # test for this later, but hopefully will know what # they're doing 'consider-using-get', # if it can figure out that the default value is something # simple, we will turn back on, but until then, no. 'chained-comparison', # sometimes simpler that way - # 'duplicate-code', # needs to ignore strings -- keeps getting doctests... + # 'duplicate-code', # needs to ignore strings -- keeps getting doctests 'too-many-ancestors', # -- 8 is okay. - 'fixme', # known... - 'superfluous-parens', # nope -- if they make things clearer... + 'fixme', # known + 'superfluous-parens', # nope -- if they make things clearer 'too-many-locals', # no 'bad-whitespace', # maybe later, but "bad" isn't something I necessarily agree with 'bad-continuation', # never remove -- this is a good thing many times. # AbstractDiatonicScale.__eq__ shows how this - # can be fine... + # can be fine 'too-many-boolean-expressions', 'unsubscriptable-object', # unfortunately, thinks that Streams are unsubscriptable. @@ -122,7 +122,7 @@ def main(fnAccept=None, strict=False): 'consider-iterating-dictionary', 'consider-using-dict-items', # readability improvement depends on excellent variable names - 'invalid-name', # these are good music21 names; fix the regexp instead... + 'invalid-name', # these are good music21 names; fix the regexp instead # 'no-self-use', # no-self-use was moved to an optional extension 'too-few-public-methods', # never remove or set to 1 @@ -132,14 +132,14 @@ def main(fnAccept=None, strict=False): 'trailing-newlines', 'missing-docstring', # gets too many well-documented properties - 'star-args', # no problem with them... + 'star-args', # no problem with them 'unused-argument', - 'import-self', # fix is either to get rid of it or move away many tests... + 'import-self', # fix is either to get rid of it or move away many tests 'simplifiable-if-statement', # NO! NO! NO! # if (x or y and z and q): return True, else: return False, # is a GREAT paradigm -- over "return (x or y and z and q)" and - # assuming that it returns a bool... it is not any slower than + # assuming that it returns a bool it is not any slower than # the simplification and it's so much clearer. 'consider-using-enumerate', # good when i used only once, but # x[i] = y[i] is a nice paradigm, even if one can be simplified out. @@ -173,7 +173,7 @@ def main(fnAccept=None, strict=False): '--reports=n', '--max-branches=' + str(maxBranches), '-j ' + str(poolSize), # multiprocessing! - r'--ignore-long-lines="converter\.parse"', # some tiny notation... + r'--ignore-long-lines="converter\.parse"', # some tiny notation '--max-line-length=100', ] for gn, gnv in goodNameRx.items(): diff --git a/music21/test/testRunner.py b/music21/test/testRunner.py index 1af7ee9690..abf3808ab0 100644 --- a/music21/test/testRunner.py +++ b/music21/test/testRunner.py @@ -140,7 +140,7 @@ def fix312OrderedDict(textString, replacement='...') -> str: ''' Function that fixes the OrderedDicts to work on Python 3.12 and above. (eventually when 3.12 is the norm, this should be replaced to neuter - the doctests for 3.10/3.11 instead.) + the doctests for 3.10/3.11 instead. Or just wait until 3.12 is the minimum version?) >>> fix312 = test.testRunner.fix312OrderedDict >>> fix312('OrderedDict([(0, 1), (1, 2), (2, 3)])') @@ -311,7 +311,7 @@ def testHello(self): s2 = unittest.defaultTestLoader.loadTestsFromTestCase(t) s1.addTests(s2) - # Add _DOC_ATTR tests... + # Add _DOC_ATTR tests if not skipDoctest: stacks = inspect.stack() if len(stacks) > 1: diff --git a/music21/test/testSerialization.py b/music21/test/testSerialization.py index 85aa58df8e..f7d9914863 100644 --- a/music21/test/testSerialization.py +++ b/music21/test/testSerialization.py @@ -159,7 +159,7 @@ def testBasicI(self): def testSpannerSerializationOfNotesNotInPickle(self): ''' test to see if spanners serialize properly if they - contain notes not in the pickle... + contain notes not in the pickle ''' from music21 import stream from music21 import spanner @@ -181,7 +181,7 @@ def testBigCorpus(self): from music21 import corpus from music21 import converter # import time - # print(time.time()) # 8.3 sec from pickle; 10.3 sec for forceSource... + # print(time.time()) # 8.3 sec from pickle; 10.3 sec for forceSource # s = corpus.parse('beethoven/opus133') #, forceSource = True) # print(time.time()) # purePython: 33! sec; cPickle: 25 sec # data = converter.freezeStr(s, fmt='pickle') diff --git a/music21/test/testSingleCoreAll.py b/music21/test/testSingleCoreAll.py index 3a0cc02846..c6ca26fc59 100644 --- a/music21/test/testSingleCoreAll.py +++ b/music21/test/testSingleCoreAll.py @@ -114,7 +114,7 @@ def main(testGroup: Sequence[str] = ('test',), environLocal.printDebug('running Tests...\n') with warnings.catch_warnings(): - warnings.simplefilter('once', RuntimeWarning) # import modules... + warnings.simplefilter('once', RuntimeWarning) # import modules warnings.simplefilter('ignore', FutureWarning) # a lot of these scipy->numpy runner = unittest.TextTestRunner(verbosity=verbosity) finalTestResults = runner.run(s1) diff --git a/music21/test/test_base.py b/music21/test/test_base.py index 7f0ea16fc2..2df461a91f 100644 --- a/music21/test/test_base.py +++ b/music21/test/test_base.py @@ -871,11 +871,11 @@ def testNextC(self): m0viaPrev = measures[3].previous('Measure').previous('Measure').previous('Measure') self.assertEqual(m0viaPrev, measures[0]) - m0viaPrev.activeSite = s.parts[0] # otherwise there are no instruments... + m0viaPrev.activeSite = s.parts[0] # otherwise there are no instruments sopranoInst = m0viaPrev.previous() self.assertEqual(str(sopranoInst), 'P1: Soprano: Instrument 1') - # set active site back to measure stream... + # set active site back to measure stream self.assertEqual(str(measures[0].previous()), str(p1)) def testActiveSiteCopyingA(self): @@ -895,9 +895,9 @@ def testSpannerSites(self): ss = n1.getSpannerSites() self.assertEqual(ss, [sp1]) - # test same for inherited classes and multiple sites, in order... + # test same for inherited classes and multiple sites, in order sp2 = dynamics.Crescendo(n2, n1) - # can return in arbitrary order esp. if speed is fast... + # can return in arbitrary order esp. if speed is fast # TODO: use Ordered Dict. self.assertEqual(set(n2.getSpannerSites()), {sp1, sp2}) @@ -964,7 +964,7 @@ def testContextSitesA(self): siteList = [] cParts = c.parts.stream() # need this otherwise it could possibly be garbage collected. - cParts.id = 'partStream' # to make it easier to see below, will be cached... + cParts.id = 'partStream' # to make it easier to see below, will be cached pTemp = cParts[1] m3 = pTemp.measure(3) self.assertIs(m, m3) @@ -1051,7 +1051,7 @@ def testContextInconsistentArguments(self): followDerivation=True ) -# great isolation test, but no asserts for now... +# great isolation test, but no asserts for now # def testPreviousA(self): # s = corpus.parse('bwv66.6') # o = s.parts[0].getElementsByClass(stream.Measure)[2][1] @@ -1111,7 +1111,7 @@ def testPreviousAfterDeepcopy(self): self.assertIs(v[1][0].previous('Note'), e1) w = v.transpose('M3') # same as deepcopy, - # but more instructive in debugging since pitches change... + # but more instructive in debugging since pitches change # w = copy.deepcopy(v) eCopy1 = w[0][0] self.assertEqual(eCopy1.pitch.name, 'E') diff --git a/music21/test/test_metadata.py b/music21/test/test_metadata.py index 4e515fff3c..c868fef01c 100644 --- a/music21/test/test_metadata.py +++ b/music21/test/test_metadata.py @@ -204,7 +204,7 @@ def checkUniqueNamedItem( if ':' not in namespaceName: # It's just the namespace because name == uniqueName, - # and I didn't want to spend the time to type it twice... + # and I didn't want to spend the time to type it twice namespaceName += ':' + uniqueName if namespaceName.startswith('marcrel'): diff --git a/music21/test/toggleDebug.py b/music21/test/toggleDebug.py index 11798050ea..3a47b891ba 100644 --- a/music21/test/toggleDebug.py +++ b/music21/test/toggleDebug.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # Name: test.toggleDebug.py -# Purpose: Changes debug on if off, off if on... +# Purpose: Changes debug on if off, off if on # # Authors: Michael Scott Asato Cuthbert # diff --git a/music21/test/treeYield.py b/music21/test/treeYield.py index eb8875165e..a6d297d041 100644 --- a/music21/test/treeYield.py +++ b/music21/test/treeYield.py @@ -55,7 +55,7 @@ def run(self, obj, memo=None): if self.yieldValue(obj) is True: yield obj - # now check for sub values... + # now check for sub values self.currentStack.append(obj) tObj = type(obj) @@ -76,7 +76,7 @@ def run(self, obj, memo=None): yield from self.run(x, memo=memo) self.stackVals.pop() - else: # objects or uncaught types... + else: # objects or uncaught types # from http://bugs.python.org/file18699/static.py try: instance_dict = object.__getattribute__(obj, '__dict__') @@ -106,7 +106,7 @@ def currentLevel(self): if stackType == 'dict': if isinstance(stackValue, str): currentStr += "['" + stackValue + "']" - else: # numeric key... + else: # numeric key currentStr += '[' + str(stackValue) + ']' elif stackType == 'listLike': currentStr += '[' + str(stackValue) + ']' diff --git a/music21/test/warningMultiprocessTest.py b/music21/test/warningMultiprocessTest.py index a7299132ea..c01905639e 100644 --- a/music21/test/warningMultiprocessTest.py +++ b/music21/test/warningMultiprocessTest.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ''' -Runs MultiprocessTest with all warnings including traceback... +Runs MultiprocessTest with all warnings including traceback ''' # # https://stackoverflow.com/questions/22373927/get-traceback-of-warnings diff --git a/music21/tie.py b/music21/tie.py index 5d74722827..f69afd462c 100644 --- a/music21/tie.py +++ b/music21/tie.py @@ -113,7 +113,7 @@ def __init__(self, type='start'): f'Type must be one of {self.VALID_TIE_TYPES}, not {type}') # naming this 'type' was a mistake, because cannot create a property of this name. - # this is not the correct way we want to do this, I don't think... + # this is not the correct way we want to do this, I don't think self.id = id(self) self.type = type self.style = 'normal' # or dashed diff --git a/music21/tinyNotation.py b/music21/tinyNotation.py index 65b3b69de7..dc0001b1a0 100644 --- a/music21/tinyNotation.py +++ b/music21/tinyNotation.py @@ -322,7 +322,7 @@ def affectTokenAfterParse( if self.autoExpires is not False: if len(self.affectedTokens) == self.autoExpires: self.end() - # this is a hack that should be done away with... + # this is a hack that should be done away with p = self.parent if p is None: return m21Obj diff --git a/music21/tree/core.py b/music21/tree/core.py index b1f12bf773..7e498f0dc1 100644 --- a/music21/tree/core.py +++ b/music21/tree/core.py @@ -39,7 +39,7 @@ class AVLNode(common.SlottedObjectMixin): >>> node - Nodes can rebalance themselves, but they work best in a Tree... + Nodes can rebalance themselves, but they work best in a Tree. Please consult the Wikipedia entry on AVL trees (https://en.wikipedia.org/wiki/AVL_tree) for a very detailed @@ -625,7 +625,7 @@ def recurse(node, innerPosition): ''' if node is None: # if we get to the point where a node does not have a - # left or right child, make a new node at this position... + # left or right child, make a new node at this position return self.nodeClass(innerPosition) if innerPosition < node.position: @@ -717,7 +717,7 @@ def getNodeAfter(self, position): >>> note1 = score.flatten().notes[30] - Works with sortTuple positions as well... + Works with sortTuple positions as well: >>> st = note1.sortTuple() >>> st diff --git a/music21/tree/fromStream.py b/music21/tree/fromStream.py index b56bb5e1cc..11ea4b23ab 100644 --- a/music21/tree/fromStream.py +++ b/music21/tree/fromStream.py @@ -231,7 +231,7 @@ def recurseGetTreeByClass( if element.isStream and flatten is not False: # True or 'semiFlat' localParentage = currentParentage + (element,) - recurseGetTreeByClass(element, # put the elements into the current tree... + recurseGetTreeByClass(element, # put the elements into the current tree currentParentage=localParentage, initialOffset=flatOffset, inner_outputTree=inner_outputTree) @@ -261,7 +261,7 @@ def recurseGetTreeByClass( return inner_outputTree - # first time through... + # first time through treeClass: type[trees.ElementTree] if useTimespans: diff --git a/music21/tree/spans.py b/music21/tree/spans.py index aa0c33150c..d5e10917d6 100644 --- a/music21/tree/spans.py +++ b/music21/tree/spans.py @@ -51,7 +51,7 @@ class Timespan: >>> print(timespan) - A timespan has two attributes, its offset and its endTime. They are immutable... + A timespan has two attributes, its offset and its endTime. They are immutable. >>> timespan.offset -1.5 @@ -468,7 +468,7 @@ def getParentageByClass(self, classList): >>> pitchedTimespan.getParentageByClass(classList=(stream.Score,)) - The closest parent is returned in case of a multiple list... + The closest parent is returned in case of a multiple list: >>> searchTuple = (stream.Voice, stream.Measure, stream.Part) >>> pitchedTimespan.getParentageByClass(classList=searchTuple) diff --git a/music21/tree/timespanTree.py b/music21/tree/timespanTree.py index fabe7db212..6f0fbeabcc 100644 --- a/music21/tree/timespanTree.py +++ b/music21/tree/timespanTree.py @@ -107,7 +107,7 @@ class TimespanTree(trees.OffsetTree): (26.5, 9.5) Example: Remove neighbor tones from the Bach chorale. (It's actually quite viscous - in its pruning...) + in its pruning.) Here in Alto, measure 7, there's a neighbor tone E#. @@ -169,7 +169,7 @@ def _insertCorePayloadSortKey(x): # if hasattr(x, 'element'): # return x.element.sortTuple()[2:] # elif isinstance(x, TimespanTree) and x.source is not None: - # environLocal.printDebug("Timespan tree added to Tree...nope...") + # environLocal.printDebug("Timespan tree added to Tree: nope.") # return x.source.sortTuple()[2:] # else: # return x.endTime # PitchedTimespan with no Element! @@ -189,7 +189,7 @@ def index(self, span): r''' Gets index of a TimeSpan in a TimespanTree. - Since Timespans do not have .sites, there is only one offset to deal with... + Since Timespans do not have .sites, there is only one offset to deal with >>> tsList = [(0, 2), (0, 9), (1, 1), (2, 3), (3, 4), ... (4, 9), (5, 6), (5, 8), (6, 8), (7, 7)] @@ -234,13 +234,13 @@ def offset(self): def removeTimespanList(self, elements, offsets=None, runUpdate=True): ''' - this will eventually be different from above... + this will eventually be different from above ''' self.removeElements(elements, offsets, runUpdate) def removeTimespan(self, elements, offsets=None, runUpdate=True): ''' - this will eventually be different from above... + this will eventually be different from above. ''' self.removeElements(elements, offsets, runUpdate) @@ -803,7 +803,7 @@ def element(self): ''' defined so a TimespanTree can be used like an PitchedTimespan - TODO: Look at subclassing or at least deriving from a common base... + TODO: Look at subclassing or at least deriving from a common base. ''' return common.unwrapWeakref(self._source) diff --git a/music21/tree/trees.py b/music21/tree/trees.py index 30b72debd9..4af59678aa 100644 --- a/music21/tree/trees.py +++ b/music21/tree/trees.py @@ -73,7 +73,7 @@ class ElementTree(core.AVLTree): >>> n2 = s[-1] - These operations are very fast... + These operations are very fast >>> et.index(n2, n2.sortTuple()) 99 @@ -193,7 +193,7 @@ def __getitem__(self, i): >>> scoreTree[2000] is None True - Slices... + Slices work >>> scoreTree[2:5] [, , ] @@ -348,7 +348,7 @@ def __str__(self): ''' Print the whole contents of the tree. - Slow: O(n log n) time, but it's just for debugging... + Slow: O(n log n) time, but it's just for debugging >>> score = tree.makeExampleScore() >>> scoreTree = score.asTree(flatten=True) @@ -388,7 +388,8 @@ def __iter__(self): r''' Iterates through all the nodes in the offset tree and returns each node's payload - Not an especially efficient way of using this beautiful tree object... + Not an especially efficient way of using this beautiful tree object! But useful + for debugging or a final iteration for conversion. >>> score = tree.makeExampleScore() >>> scoreTree = score.asTree(flatten=True) @@ -580,7 +581,7 @@ def getNodeByIndex(self, i): ''' Get a node whose element is at a particular index (not position). Works with slices too - See __getitem__ for caveats about speed... + See __getitem__ for caveats about speed. >>> score = tree.makeExampleScore() >>> scoreTree = score.asTree(flatten=True) @@ -772,7 +773,7 @@ def insert(self, positionsOrElements, elements=None): else: positions = positionsOrElements if not common.isListLike(positions) or hasattr(positions, 'shortRepr'): - # is not a list and not a sortTuple... + # is not a list and not a sortTuple positions = [positions] if (not common.isListLike(elements) @@ -862,7 +863,7 @@ def source(self): @source.setter def source(self, expr): - # uses weakrefs so that garbage collection on the stream cache is possible... + # uses weakrefs so that garbage collection on the stream cache is possible self._source = common.wrapWeakref(expr) @property @@ -1064,7 +1065,7 @@ def __iter__(self): Iterates through all the nodes in the offset tree and returns each thing in the payload. - Not an especially efficient way of using this beautiful tree object... + Not an especially efficient way of using this beautiful tree object. >>> score = tree.makeExampleScore() >>> scoreTree = score.asTree(flatten=True, groupOffsets=True) @@ -1254,7 +1255,7 @@ def recurse(node): if node is not None: if node.position < offset < node.endTimeHigh: result.extend(recurse(node.leftChild)) - # This currently requires timespans not elements, and list payloads... + # This currently requires timespans not elements, and list payloads # TODO: Fix/disambiguate. for el in node.payload: if offset < self.elementEndTime(el, node): @@ -1406,12 +1407,12 @@ def getVerticalityAt(self, offset): >>> scoreTree.getVerticalityAt(2.5) - Verticalities outside the range still return a Verticality, but it might be empty... + Verticalities outside the range still return a Verticality, but it might be empty: >>> scoreTree.getVerticalityAt(2000) - Test that it still works if the tree is empty... + Test that it still works if the tree is empty: >>> scoreTree = bach.asTimespans(classList=(instrument.Tuba,)) >>> scoreTree diff --git a/music21/tree/verticality.py b/music21/tree/verticality.py index fba1046cde..90c0b02a46 100644 --- a/music21/tree/verticality.py +++ b/music21/tree/verticality.py @@ -763,7 +763,7 @@ def makeElement( r.duration.quarterLength = quarterLength return r - # easy stuff done, time to get to the hard stuff... + # easy stuff done, time to get to the hard stuff c = chord.Chord() c.duration.quarterLength = quarterLength @@ -949,7 +949,7 @@ def conditionalAdd(ts: spans.PitchedTimespan, n: note.Note) -> None: return c - # Analysis type things... + # Analysis type things @overload def getAllVoiceLeadingQuartets( self, @@ -1175,7 +1175,7 @@ def getPairedMotion( previousTs = self.timespanTree.findPreviousPitchedTimespanInSameStreamByClass( startingTs) if previousTs is None or not isinstance(previousTs, spans.PitchedTimespan): - continue # first not in piece in this part... + continue # first not in piece in this part if includeRests is False: if previousTs not in stopTss: diff --git a/music21/variant.py b/music21/variant.py index 30b3a528b9..5d963b152b 100644 --- a/music21/variant.py +++ b/music21/variant.py @@ -140,7 +140,7 @@ def __getattr__(self, attr): if attr in ['flat', 'pitches']: raise AttributeError - # needed for unpickling where ._stream doesn't exist until later... + # needed for unpickling where ._stream doesn't exist until later if attr != '_stream' and hasattr(self, '_stream'): return getattr(self._stream, attr) else: @@ -422,7 +422,7 @@ def replacedElements(self, contextStream=None, classList=None, 'No contextStream or activeSite, finding most recently added site (dangerous)') contextStream = self.getContextByClass('Stream') if contextStream is None: - raise VariantException('Cannot find a Stream context for this object...') + raise VariantException('Cannot find a Stream context for this object.') if self not in contextStream.getElementsByClass(self.__class__): raise VariantException(f'Variant not found in stream {contextStream}') @@ -551,7 +551,7 @@ def removeReplacedElementsFromStream(self, referenceStream=None, classList=None) + 'finding most recently added site (dangerous)') referenceStream = self.getContextByClass('Stream') if referenceStream is None: - raise VariantException('Cannot find a Stream context for this object...') + raise VariantException('Cannot find a Stream context for this object.') if self not in referenceStream.getElementsByClass(self.__class__): raise VariantException(f'Variant not found in stream {referenceStream}') diff --git a/music21/vexflow/toMusic21j.py b/music21/vexflow/toMusic21j.py index 8a8b4c8ca6..07007405b6 100644 --- a/music21/vexflow/toMusic21j.py +++ b/music21/vexflow/toMusic21j.py @@ -257,7 +257,7 @@ def fromStream(self, thisStream, mode=None): sf = freezeThaw.StreamFreezer(thisStream) # recursive data structures will be expanded up to a high depth - # -- make sure there are none... + # -- make sure there are none data = sf.writeStr(fmt='jsonpickle') dataSplit = self.splitLongJSON(data) if mode == 'json': @@ -286,7 +286,7 @@ class TestCuthbert(unittest.TestCase): # pragma: no cover def testCuthbertLocal(self): ''' - test a local version of this mess... + test a local version of this mess ''' from music21 import corpus from music21 import environment diff --git a/music21/voiceLeading.py b/music21/voiceLeading.py index ad107fdc0b..ba7fb2a37a 100644 --- a/music21/voiceLeading.py +++ b/music21/voiceLeading.py @@ -350,7 +350,7 @@ def motionType(self, *, allowAntiParallel=False): No motion (if I had a dollar for every time I forgot to teach - that this is not a form of oblique motion...): + that this is not a form of oblique motion): >>> m1_f4 = note.Note('F4') # C5, C5 against F4, F4 >>> vl = voiceLeading.VoiceLeadingQuartet(n1_c5, n2_c5, m1_f4, m2_f4) @@ -842,8 +842,9 @@ def parallelFifth(self) -> bool: def parallelOctave(self) -> bool: ''' - Returns True if the motion is a parallel Perfect Octave... - a concept so abhorrent we shudder to illustrate it with an example, but alas, we must: + Returns True if the motion is a parallel Perfect Octave. + + (This is a concept so abhorrent we shudder to illustrate it with an example, but alas, we must:) We will make the examples shorter with this abbreviation: >>> N = note.Note @@ -861,6 +862,8 @@ def parallelOctave(self) -> bool: >>> vlq = voiceLeading.VoiceLeadingQuartet(N('C4'), N('D4'), N('C4'), N('D4')) >>> vlq.parallelOctave() False + + (P.S., we were joking about parallel octaves being abhorant or out of God's creation!) ''' return self.parallelInterval(self.octave) diff --git a/music21/volume.py b/music21/volume.py index 02c7315eb0..2b3a83d5ac 100644 --- a/music21/volume.py +++ b/music21/volume.py @@ -218,13 +218,13 @@ def getRealized( >>> s.notes[7].volume.getRealized() 0.99212... - velocity, if set, will be scaled by dynamics + velocity, if set, will be scaled by dynamics: >>> s.notes[7].volume.velocity = 20 >>> s.notes[7].volume.getRealized() 0.22047... - unless we set the velocity to not be relative... + Unless we set the velocity to not be relative: >>> s.notes[7].volume.velocityIsRelative = False >>> s.notes[7].volume.getRealized() From bfa6e94ab18b9335d408b3884a05567cd477acd6 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 28 Oct 2024 16:41:07 -1000 Subject: [PATCH 2/3] fix lint -- update copyright --- dist/dist.py | 2 +- documentation/source/about/about.rst | 2 +- documentation/source/conf.py | 2 +- documentation/testDocumentation.py | 2 +- music21/__init__.py | 2 +- music21/abcFormat/translate.py | 3 +- music21/alpha/__init__.py | 3 +- music21/base.py | 2 +- music21/beam.py | 5 ++-- music21/chord/__init__.py | 2 +- music21/clef.py | 2 +- music21/common/types.py | 2 +- music21/corpus/corpora.py | 3 +- music21/derivation.py | 3 +- music21/duration.py | 2 +- music21/editorial.py | 3 +- music21/environment.py | 3 +- music21/expressions.py | 2 +- music21/figuredBass/harmony.py | 2 +- music21/freezeThaw.py | 3 +- music21/graph/utilities.py | 2 +- music21/harmony.py | 5 ++-- music21/interval.py | 2 +- music21/license.txt | 4 +-- music21/lily/translate.py | 2 +- music21/metadata/__init__.py | 3 +- music21/metadata/caching.py | 3 +- music21/metadata/primitives.py | 2 +- music21/metadata/properties.py | 3 +- music21/meter/__init__.py | 2 +- music21/meter/base.py | 2 +- music21/meter/core.py | 2 +- music21/meter/tests.py | 2 +- music21/meter/tools.py | 2 +- music21/musedata/__init__.py | 41 ++++++++++++++-------------- music21/musicxml/archiveTools.py | 2 +- music21/musicxml/xmlObjects.py | 2 +- music21/musicxml/xmlToM21.py | 2 +- music21/note.py | 2 +- music21/roman.py | 2 +- music21/scale/test_scale_main.py | 2 +- music21/sorting.py | 3 +- music21/spanner.py | 3 +- music21/stream/base.py | 2 +- music21/stream/core.py | 2 +- music21/stream/iterator.py | 2 +- music21/stream/makeNotation.py | 2 +- music21/stream/streamStatus.py | 3 +- music21/stream/tests.py | 2 +- music21/style.py | 3 +- music21/test/testLint.py | 2 +- music21/test/testRunner.py | 3 +- music21/test/test_base.py | 2 +- music21/test/test_pitch.py | 2 +- music21/tinyNotation.py | 2 +- music21/tree/__init__.py | 3 +- music21/tree/analysis.py | 3 +- music21/tree/core.py | 3 +- music21/tree/fromStream.py | 3 +- music21/tree/node.py | 3 +- music21/tree/spans.py | 3 +- music21/tree/timespanTree.py | 3 +- music21/tree/toStream.py | 3 +- music21/tree/trees.py | 3 +- music21/tree/verticality.py | 3 +- music21/voiceLeading.py | 12 +++++--- 66 files changed, 98 insertions(+), 116 deletions(-) diff --git a/dist/dist.py b/dist/dist.py index f7a29a0224..77ca57b4c1 100644 --- a/dist/dist.py +++ b/dist/dist.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2010-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2010-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/documentation/source/about/about.rst b/documentation/source/about/about.rst index 29fe309bc6..1b6c1d5f38 100644 --- a/documentation/source/about/about.rst +++ b/documentation/source/about/about.rst @@ -174,7 +174,7 @@ Licensing and Copyright The `music21` Toolkit ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Music21 is Copyright © 2006-2023 Michael Scott Asato Cuthbert. +Music21 is Copyright © 2006-2024 Michael Scott Asato Cuthbert. Music21 code (excluding content encoded in the corpus) is free and open-source software, licensed under the BSD License. diff --git a/documentation/source/conf.py b/documentation/source/conf.py index c3abe30485..bc23975ac5 100644 --- a/documentation/source/conf.py +++ b/documentation/source/conf.py @@ -48,7 +48,7 @@ project = 'music21' # pylint: disable=redefined-builtin # noinspection PyShadowingBuiltins -copyright = '2006-2023 Michael Scott Asato Cuthbert' +copyright = '2006-2024 Michael Scott Asato Cuthbert' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/documentation/testDocumentation.py b/documentation/testDocumentation.py index 4236f26c63..f32adc7275 100644 --- a/documentation/testDocumentation.py +++ b/documentation/testDocumentation.py @@ -5,7 +5,7 @@ # # Authors: Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2010-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2010-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/music21/__init__.py b/music21/__init__.py index aca185ffb1..61b0ebf3b5 100644 --- a/music21/__init__.py +++ b/music21/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ''' -The music21 Framework is Copyright © 2006-2023 Michael Scott Asato Cuthbert. +The music21 Framework is Copyright © 2006-2024 Michael Scott Asato Cuthbert. Some Rights Reserved Released under the BSD (3-clause) license. See license.txt. diff --git a/music21/abcFormat/translate.py b/music21/abcFormat/translate.py index 6b8a8d6300..091309f087 100644 --- a/music21/abcFormat/translate.py +++ b/music21/abcFormat/translate.py @@ -7,8 +7,7 @@ # Michael Scott Asato Cuthbert # Dylan Nagler # -# Copyright: Copyright © 2010-2023 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2010-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/alpha/__init__.py b/music21/alpha/__init__.py index f641dd8061..719fd1493a 100644 --- a/music21/alpha/__init__.py +++ b/music21/alpha/__init__.py @@ -5,8 +5,7 @@ # # Authors: Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2015 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/base.py b/music21/base.py index b32e1082d3..b9c3861db2 100644 --- a/music21/base.py +++ b/music21/base.py @@ -6,7 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2006-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2006-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/beam.py b/music21/beam.py index 3478efc7bf..6787f85adf 100644 --- a/music21/beam.py +++ b/music21/beam.py @@ -1,13 +1,12 @@ # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Name: beam.py -# Purpose: music21 classes for representing notes +# Purpose: music21 classes for representing beams and beam groups # # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2009-2012, 19 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2009-2012, 2019 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/chord/__init__.py b/music21/chord/__init__.py index 1888cc9768..99373fb913 100644 --- a/music21/chord/__init__.py +++ b/music21/chord/__init__.py @@ -6,7 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/music21/clef.py b/music21/clef.py index 29746e3f98..fa44f70168 100644 --- a/music21/clef.py +++ b/music21/clef.py @@ -7,7 +7,7 @@ # Christopher Ariza # Michael Bodenbach # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/music21/common/types.py b/music21/common/types.py index 8d2eccf662..1dfc0aeeba 100644 --- a/music21/common/types.py +++ b/music21/common/types.py @@ -5,7 +5,7 @@ # # Authors: Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2021-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2021-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ from __future__ import annotations diff --git a/music21/corpus/corpora.py b/music21/corpus/corpora.py index 10b03635bd..d89e03dfbf 100644 --- a/music21/corpus/corpora.py +++ b/music21/corpus/corpora.py @@ -5,8 +5,7 @@ # # Authors: Josiah Wolf Oberholtzer # -# Copyright: Copyright © 2009-2012, 2014 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2009-2012, 2014 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- from __future__ import annotations diff --git a/music21/derivation.py b/music21/derivation.py index c27d7e99f0..a0db84e3a4 100644 --- a/music21/derivation.py +++ b/music21/derivation.py @@ -7,8 +7,7 @@ # Josiah Oberholtzer # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2011-2014 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2011-2014 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ---------------------------------------------------------------------------- ''' diff --git a/music21/duration.py b/music21/duration.py index 784f684c5a..17717dabb0 100644 --- a/music21/duration.py +++ b/music21/duration.py @@ -6,7 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2008-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2008-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/music21/editorial.py b/music21/editorial.py index eeeb75e45c..f2f1e1073e 100644 --- a/music21/editorial.py +++ b/music21/editorial.py @@ -6,8 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2008-2015 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2008-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/environment.py b/music21/environment.py index dad04e3749..0987d1b945 100644 --- a/music21/environment.py +++ b/music21/environment.py @@ -6,8 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2017 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2009-2017 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/expressions.py b/music21/expressions.py index c56c9782ab..c1adb8dde5 100644 --- a/music21/expressions.py +++ b/music21/expressions.py @@ -7,7 +7,7 @@ # Christopher Ariza # Neena Parikh # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/music21/figuredBass/harmony.py b/music21/figuredBass/harmony.py index aa456d3cd7..c2f190ad6e 100644 --- a/music21/figuredBass/harmony.py +++ b/music21/figuredBass/harmony.py @@ -5,7 +5,7 @@ # Authors: Moritz Heffter # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2011-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2011-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/music21/freezeThaw.py b/music21/freezeThaw.py index 5881f97307..4c61990057 100644 --- a/music21/freezeThaw.py +++ b/music21/freezeThaw.py @@ -7,8 +7,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2011-2012 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2011-2012 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- r''' diff --git a/music21/graph/utilities.py b/music21/graph/utilities.py index 8737e88a24..971297fa87 100644 --- a/music21/graph/utilities.py +++ b/music21/graph/utilities.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert, +# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/music21/harmony.py b/music21/harmony.py index cb81127385..230332b659 100644 --- a/music21/harmony.py +++ b/music21/harmony.py @@ -8,7 +8,7 @@ # Jacob Tyler Walls # Christopher Ariza # -# Copyright: Copyright © 2011-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2011-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' @@ -1001,7 +1001,8 @@ def chordSymbolFigureFromChord(inChord: chord.Chord, includeChordType=False): * eleventh chords: third and/or fifth * thirteenth chords: fifth, eleventh, ninth - This chord could be minor 7th with a C4, but because this 5th is not present, it is not identified + This chord could be minor 7th with a C4, but because this 5th is not present, + it is not identified. >>> c = chord.Chord(['F3', 'A-3', 'E-4']) >>> harmony.chordSymbolFigureFromChord(c) diff --git a/music21/interval.py b/music21/interval.py index acaeef5b2d..450fca17eb 100644 --- a/music21/interval.py +++ b/music21/interval.py @@ -8,7 +8,7 @@ # Amy Hailes # Christopher Ariza # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/music21/license.txt b/music21/license.txt index d9e81a163d..286e2bcd0d 100644 --- a/music21/license.txt +++ b/music21/license.txt @@ -6,7 +6,7 @@ # distributed with this package, particularly the corpus files # which have their own copyrights and licenses. # -# Copyright: music21 is "Copyright © 2006-2023 Michael Scott Asato Cuthbert" +# Copyright: music21 is "Copyright © 2006-2024 Michael Scott Asato Cuthbert" # and is open-source licensed under the # BSD 3-Clause License (beginning with music21 v2.0) # reprinted below. @@ -22,7 +22,7 @@ the BSD license still under effect. --- BSD License -Copyright (c) 2006-2023 Michael Scott Asato Cuthbert +Copyright (c) 2006-2024 Michael Scott Asato Cuthbert All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/music21/lily/translate.py b/music21/lily/translate.py index c8e01e6fea..56b2b972a6 100644 --- a/music21/lily/translate.py +++ b/music21/lily/translate.py @@ -5,7 +5,7 @@ # # Authors: Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2007-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2007-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/music21/metadata/__init__.py b/music21/metadata/__init__.py index c98750fb47..5d95fd2fbb 100755 --- a/music21/metadata/__init__.py +++ b/music21/metadata/__init__.py @@ -7,8 +7,7 @@ # Greg Chapman # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2010-22 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2010-2022 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/metadata/caching.py b/music21/metadata/caching.py index f51d40cd83..f8caad9c10 100644 --- a/music21/metadata/caching.py +++ b/music21/metadata/caching.py @@ -6,8 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2010, 2012 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2010, 2012 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- from __future__ import annotations diff --git a/music21/metadata/primitives.py b/music21/metadata/primitives.py index 4d51c105d4..c553874565 100644 --- a/music21/metadata/primitives.py +++ b/music21/metadata/primitives.py @@ -7,7 +7,7 @@ # Michael Scott Asato Cuthbert # Greg Chapman # -# Copyright: Copyright © 2010-22 Michael Scott Asato Cuthbert and the music21 +# Copyright: Copyright © 2010-22 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- from __future__ import annotations diff --git a/music21/metadata/properties.py b/music21/metadata/properties.py index 91412fbead..59d7278802 100644 --- a/music21/metadata/properties.py +++ b/music21/metadata/properties.py @@ -6,8 +6,7 @@ # Authors: Greg Chapman # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2023 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2023–2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- from __future__ import annotations diff --git a/music21/meter/__init__.py b/music21/meter/__init__.py index 87a96de9a5..632ce29db7 100644 --- a/music21/meter/__init__.py +++ b/music21/meter/__init__.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- from __future__ import annotations diff --git a/music21/meter/base.py b/music21/meter/base.py index 3453410fc7..ffc0aa61c7 100644 --- a/music21/meter/base.py +++ b/music21/meter/base.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/meter/core.py b/music21/meter/core.py index 2637ccc8e7..870984dcad 100644 --- a/music21/meter/core.py +++ b/music21/meter/core.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/meter/tests.py b/music21/meter/tests.py index fef72e44d6..403280c4a5 100644 --- a/music21/meter/tests.py +++ b/music21/meter/tests.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- from __future__ import annotations diff --git a/music21/meter/tools.py b/music21/meter/tools.py index f0ff3e9f41..3a6629759a 100644 --- a/music21/meter/tools.py +++ b/music21/meter/tools.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- from __future__ import annotations diff --git a/music21/musedata/__init__.py b/music21/musedata/__init__.py index 38788ab053..69c75e7a7e 100644 --- a/music21/musedata/__init__.py +++ b/music21/musedata/__init__.py @@ -27,7 +27,7 @@ ''' from __future__ import annotations -from collections.abc import Sequence +from collections.abc import Iterable import os import typing as t import unittest @@ -59,8 +59,11 @@ class MuseDataRecord(prebase.ProtoM21Object): Object for extracting data from a Note or other related record, or a single line of musedata data. ''' - - def __init__(self, src='', parent=None): + def __init__( + self, + src: str = '', + parent=None + ): # environLocal.printDebug(['creating MuseDataRecord']) self.src = src # src here is one line of text self.parent = parent @@ -73,7 +76,7 @@ def __init__(self, src='', parent=None): # store frequently used values self._cache = {} - def isRest(self): + def isRest(self) -> bool: ''' Return a boolean if this record is a rest. @@ -83,7 +86,6 @@ def isRest(self): >>> mdr = musedata.MuseDataRecord('measure 1 A') >>> mdr.isRest() False - ''' if self.src and self.src[0] == 'r': return True @@ -516,7 +518,6 @@ def getDynamicObjects(self): >>> mdr = musedata.MuseDataRecord('E4 48 h u (pp') >>> mdr.getDynamicObjects() [] - ''' from music21 import dynamics post = [] @@ -524,25 +525,25 @@ def getDynamicObjects(self): if data is None: return post # find targets from largest to smallest - targets = ['ppp', 'fff', + targets = ('ppp', 'fff', 'pp', 'ff', 'fp', 'mp', 'mf', - 'p', 'f', 'm', 'Z', 'Zp', 'R'] - for t in targets: - pos = data.find(t) + 'p', 'f', 'm', 'Z', 'Zp', 'R') + for target in targets: + pos = data.find(target) if pos < 0: continue # remove from data to avoid double hits - data = data[:pos] + data[pos + len(t):] - # those that can be directedly created - if t in ['ppp', 'fff', 'pp', 'ff', 'p', 'f', 'mp', 'mf', 'fp']: - post.append(dynamics.Dynamic(t)) - elif t == 'm': + data = data[:pos] + data[pos + len(target):] + # those that can be directly created + if target in ('ppp', 'fff', 'pp', 'ff', 'p', 'f', 'mp', 'mf', 'fp'): + post.append(dynamics.Dynamic(target)) + elif target == 'm': post.append(dynamics.Dynamic('mp')) - elif t == 'Z': # sfz + elif target == 'Z': # sfz post.append(dynamics.Dynamic('sf')) - elif t == 'Zp': # sfp + elif target == 'Zp': # sfp post.append(dynamics.Dynamic('sf')) - elif t == 'R': # rfz + elif target == 'R': # rfz post.append(dynamics.Dynamic('sf')) # environLocal.printDebug(['got dynamics', post]) return post @@ -1553,12 +1554,12 @@ def __init__(self): self.files: list[MuseDataFile] = [] self.encoding: str = 'utf-8' - def addFile(self, fp: str | Sequence[str]) -> None: + def addFile(self, fp: str | Iterable[str]) -> None: ''' Open and read this file path or list of paths as MuseDataFile objects and set self.files ''' - fpList: Sequence[str] + fpList: Iterable[str] if not common.isIterable(fp): fp_single = t.cast(str, fp) fpList = [fp_single] diff --git a/music21/musicxml/archiveTools.py b/music21/musicxml/archiveTools.py index 1c41fac304..4840b5fc71 100644 --- a/music21/musicxml/archiveTools.py +++ b/music21/musicxml/archiveTools.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009, 2017-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009, 2017-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/musicxml/xmlObjects.py b/music21/musicxml/xmlObjects.py index c4635ef7f4..6a07ef388b 100644 --- a/music21/musicxml/xmlObjects.py +++ b/music21/musicxml/xmlObjects.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ from __future__ import annotations diff --git a/music21/musicxml/xmlToM21.py b/music21/musicxml/xmlToM21.py index a32f78b9d7..3025157e6c 100644 --- a/music21/musicxml/xmlToM21.py +++ b/music21/musicxml/xmlToM21.py @@ -7,7 +7,7 @@ # Christopher Ariza # Jacob Tyler Walls # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ from __future__ import annotations diff --git a/music21/note.py b/music21/note.py index 6982928991..1ba2e7dd38 100644 --- a/music21/note.py +++ b/music21/note.py @@ -6,7 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2006-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2006-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' diff --git a/music21/roman.py b/music21/roman.py index 061b4a5934..40c12fbe03 100644 --- a/music21/roman.py +++ b/music21/roman.py @@ -6,7 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2011-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2011-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/scale/test_scale_main.py b/music21/scale/test_scale_main.py index a65a36cd56..df9e45bdde 100644 --- a/music21/scale/test_scale_main.py +++ b/music21/scale/test_scale_main.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2010-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2010-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ from __future__ import annotations diff --git a/music21/sorting.py b/music21/sorting.py index 9ff870d9d9..b82ff53ac0 100644 --- a/music21/sorting.py +++ b/music21/sorting.py @@ -5,8 +5,7 @@ # # Authors: Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2014-2015 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2014-2015 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/spanner.py b/music21/spanner.py index 62dd2699af..0b41559dfc 100644 --- a/music21/spanner.py +++ b/music21/spanner.py @@ -584,7 +584,8 @@ def fill( >>> ott3 = spanner.Ottava(note.Note('D'), note.Note('E')) >>> ott3.fill() Traceback (most recent call last): - music21.spanner.SpannerException: Spanner.fill() requires a searchStream or getFirst().activeSite + music21.spanner.SpannerException: Spanner.fill() requires a searchStream + or getFirst().activeSite ''' if not self.fillElementTypes: diff --git a/music21/stream/base.py b/music21/stream/base.py index 242118cf71..04d1293a21 100644 --- a/music21/stream/base.py +++ b/music21/stream/base.py @@ -8,7 +8,7 @@ # Josiah Wolf Oberholtzer # Evan Lynch # -# Copyright: Copyright © 2008-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2008-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/stream/core.py b/music21/stream/core.py index 125babeae9..6605422296 100644 --- a/music21/stream/core.py +++ b/music21/stream/core.py @@ -6,7 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2008-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2008-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/stream/iterator.py b/music21/stream/iterator.py index 636cde4713..e545e8fe29 100644 --- a/music21/stream/iterator.py +++ b/music21/stream/iterator.py @@ -6,7 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2008-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2008-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/stream/makeNotation.py b/music21/stream/makeNotation.py index 43e6d97fd1..cc4824d92b 100644 --- a/music21/stream/makeNotation.py +++ b/music21/stream/makeNotation.py @@ -8,7 +8,7 @@ # Jacob Walls # Evan Lynch # -# Copyright: Copyright © 2008-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2008-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- from __future__ import annotations diff --git a/music21/stream/streamStatus.py b/music21/stream/streamStatus.py index d1b179da57..21196cfdf1 100644 --- a/music21/stream/streamStatus.py +++ b/music21/stream/streamStatus.py @@ -5,8 +5,7 @@ # # Authors: Josiah Wolf Oberholtzer # -# Copyright: Copyright © 2013 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- from __future__ import annotations diff --git a/music21/stream/tests.py b/music21/stream/tests.py index 506b25c7e9..adb2633651 100644 --- a/music21/stream/tests.py +++ b/music21/stream/tests.py @@ -6,7 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ from __future__ import annotations diff --git a/music21/style.py b/music21/style.py index c402c7cf2d..f01501c252 100644 --- a/music21/style.py +++ b/music21/style.py @@ -5,8 +5,7 @@ # # Authors: Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2016-22 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2016-2022 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/test/testLint.py b/music21/test/testLint.py index 69208eab07..522d1472d0 100644 --- a/music21/test/testLint.py +++ b/music21/test/testLint.py @@ -6,7 +6,7 @@ # Authors: Christopher Ariza # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert, +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ from __future__ import annotations diff --git a/music21/test/testRunner.py b/music21/test/testRunner.py index abf3808ab0..f79b3e7b5e 100644 --- a/music21/test/testRunner.py +++ b/music21/test/testRunner.py @@ -6,8 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2006-2016 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2006-2016 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/test/test_base.py b/music21/test/test_base.py index 2df461a91f..c1327f4ab0 100644 --- a/music21/test/test_base.py +++ b/music21/test/test_base.py @@ -6,7 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2008-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2008-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ from __future__ import annotations diff --git a/music21/test/test_pitch.py b/music21/test/test_pitch.py index 62d021a882..b6f9783a61 100644 --- a/music21/test/test_pitch.py +++ b/music21/test/test_pitch.py @@ -6,7 +6,7 @@ # Authors: Michael Scott Asato Cuthbert # Christopher Ariza # -# Copyright: Copyright © 2008-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2008-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ from __future__ import annotations diff --git a/music21/tinyNotation.py b/music21/tinyNotation.py index dc0001b1a0..6a5523e166 100644 --- a/music21/tinyNotation.py +++ b/music21/tinyNotation.py @@ -5,7 +5,7 @@ # # Authors: Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------- ''' diff --git a/music21/tree/__init__.py b/music21/tree/__init__.py index 73abfbcf9c..4e099fbac9 100644 --- a/music21/tree/__init__.py +++ b/music21/tree/__init__.py @@ -7,8 +7,7 @@ # Authors: Josiah Wolf Oberholtzer # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2013-15 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013-2015 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/tree/analysis.py b/music21/tree/analysis.py index ff35b2ac04..a8d621501a 100644 --- a/music21/tree/analysis.py +++ b/music21/tree/analysis.py @@ -5,8 +5,7 @@ # # Authors: Josiah Wolf Oberholtzer # -# Copyright: Copyright © 2013-14 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013-2014 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/tree/core.py b/music21/tree/core.py index 7e498f0dc1..cf83ef3135 100644 --- a/music21/tree/core.py +++ b/music21/tree/core.py @@ -6,8 +6,7 @@ # Authors: Josiah Wolf Oberholtzer # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2013-16 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013-2016 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/tree/fromStream.py b/music21/tree/fromStream.py index 11ea4b23ab..499973db77 100644 --- a/music21/tree/fromStream.py +++ b/music21/tree/fromStream.py @@ -6,8 +6,7 @@ # Authors: Josiah Wolf Oberholtzer # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2013-22 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013-2022 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/tree/node.py b/music21/tree/node.py index 191543c4ba..fb5cf8b4f4 100644 --- a/music21/tree/node.py +++ b/music21/tree/node.py @@ -6,8 +6,7 @@ # Authors: Josiah Wolf Oberholtzer # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2013-16 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013-2016 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/tree/spans.py b/music21/tree/spans.py index d5e10917d6..1c0eb87e82 100644 --- a/music21/tree/spans.py +++ b/music21/tree/spans.py @@ -7,8 +7,7 @@ # Authors: Josiah Wolf Oberholtzer # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2013-15 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/tree/timespanTree.py b/music21/tree/timespanTree.py index 6f0fbeabcc..7525535cba 100644 --- a/music21/tree/timespanTree.py +++ b/music21/tree/timespanTree.py @@ -6,8 +6,7 @@ # Authors: Josiah Wolf Oberholtzer # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2013-16 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/tree/toStream.py b/music21/tree/toStream.py index e6ee5cd2a7..7c0eede6a9 100644 --- a/music21/tree/toStream.py +++ b/music21/tree/toStream.py @@ -6,8 +6,7 @@ # Authors: Josiah Wolf Oberholtzer # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2013-15 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013-2015 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/tree/trees.py b/music21/tree/trees.py index 4af59678aa..f1f316bd1d 100644 --- a/music21/tree/trees.py +++ b/music21/tree/trees.py @@ -6,8 +6,7 @@ # Authors: Josiah Wolf Oberholtzer # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2013-16 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013-2016 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ----------------------------------------------------------------------------- ''' diff --git a/music21/tree/verticality.py b/music21/tree/verticality.py index 90c0b02a46..50f9eeacc3 100644 --- a/music21/tree/verticality.py +++ b/music21/tree/verticality.py @@ -7,8 +7,7 @@ # Authors: Josiah Wolf Oberholtzer # Michael Scott Asato Cuthbert # -# Copyright: Copyright © 2013-16 Michael Scott Asato Cuthbert and the music21 -# Project +# Copyright: Copyright © 2013-2016 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ---------------------------------------------------------------------------- ''' diff --git a/music21/voiceLeading.py b/music21/voiceLeading.py index ba7fb2a37a..46a39cdd88 100644 --- a/music21/voiceLeading.py +++ b/music21/voiceLeading.py @@ -8,7 +8,7 @@ # Jackie Rogoff # Beth Hadley # -# Copyright: Copyright © 2009-2023 Michael Scott Asato Cuthbert +# Copyright: Copyright © 2009-2024 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' @@ -844,9 +844,11 @@ def parallelOctave(self) -> bool: ''' Returns True if the motion is a parallel Perfect Octave. - (This is a concept so abhorrent we shudder to illustrate it with an example, but alas, we must:) + (This is a concept so abhorrent we shudder to illustrate it + with an example, but alas, we must:) We will make the examples shorter with this abbreviation: + >>> N = note.Note >>> vlq = voiceLeading.VoiceLeadingQuartet(N('C5'), N('D5'), N('C4'), N('D4')) @@ -857,13 +859,15 @@ def parallelOctave(self) -> bool: >>> vlq.parallelOctave() True - Or False if the motion is according to the rules of God's own creation: + Or False if the motion is according to the rules of God's own creation :-) >>> vlq = voiceLeading.VoiceLeadingQuartet(N('C4'), N('D4'), N('C4'), N('D4')) >>> vlq.parallelOctave() False - (P.S., we were joking about parallel octaves being abhorant or out of God's creation!) + (P.S., we were joking about parallel octaves being abhorant or out of God's creation! + music21 works just as well with popular music and other styles that do not + have problems with parallel octaves.) ''' return self.parallelInterval(self.octave) From b92727d7475a47b8a2373f1f95701e28b39c3e5b Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 28 Oct 2024 17:02:07 -1000 Subject: [PATCH 3/3] typing, mypy, lost -> list --- dist/dist.py | 2 +- music21/musedata/__init__.py | 27 ++++++++++++++------------- music21/musedata/translate.py | 2 +- music21/repeat.py | 2 +- music21/scale/__init__.py | 2 +- music21/scale/test_intervalNetwork.py | 2 +- music21/stream/tests.py | 2 +- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/dist/dist.py b/dist/dist.py index 77ca57b4c1..20d9c06155 100644 --- a/dist/dist.py +++ b/dist/dist.py @@ -14,7 +14,7 @@ To do a release, -1. update the VERSION in _version.py and the single test cases in base.py. +1. update the VERSION in _version.py and the single test case in base.py. 2. run `corpus.corpora.CoreCorpus().cacheMetadata()`. for a major change that affects parsing run corpus.corpora.CoreCorpus().rebuildMetadataCache() (20 min on IntelMacbook Air) -- either of these MAY change a diff --git a/music21/musedata/__init__.py b/music21/musedata/__init__.py index 69c75e7a7e..f1b2b9ee63 100644 --- a/music21/musedata/__init__.py +++ b/music21/musedata/__init__.py @@ -74,7 +74,7 @@ def __init__( else: self.stage = None # store frequently used values - self._cache = {} + self._cache: dict[str, str|None] = {} def isRest(self) -> bool: ''' @@ -398,9 +398,9 @@ def getBeams(self): # TODO: need to get slurs from this indication: # (), {}, [] - def _getAdditionalNotations(self): + def _getAdditionalNotations(self) -> str|None: ''' - Return an articulation object or None + Return an articulation string or None >>> mdr = musedata.MuseDataRecord('C4 12 e u [ .p') >>> mdr._getAdditionalNotations() @@ -420,16 +420,17 @@ def _getAdditionalNotations(self): except KeyError: pass + data: str|None if len(self.src) < 31: data = None else: # accumulate chars 32-43, index 31, 42 - data = [] + data_list = [] i = 31 while i <= 42 and i < len(self.src): - data.append(self.src[i]) + data_list.append(self.src[i]) i += 1 - data = ''.join(data).strip() + data = ''.join(data_list).strip() self._cache['_getAdditionalNotations'] = data return data @@ -578,7 +579,7 @@ class MuseDataRecordIterator: ''' def __init__(self, src, parent): - self.src = src # the lost of all record lines + self.src = src # the list of all record lines self.index = 0 self.parent = parent @@ -738,7 +739,7 @@ class MuseDataMeasureIterator: ''' def __init__(self, src, boundaries, parent): - self.src = src # the lost of all record lines + self.src = src # the list of all record lines self.boundaries = boundaries # pairs of all boundaries self.index = 0 self.parent = parent @@ -1468,11 +1469,11 @@ class MuseDataFile(prebase.ProtoM21Object): When read, one or more MuseDataPart objects are created and stored on self.parts. ''' - def __init__(self): - self.parts = [] # a lost of MuseDataPart objects + def __init__(self) -> None: + self.parts: list[MuseDataPart] = [] - self.filename = None - self.file = None + self.filename: str|None = None + self.file: t.BinaryIO|None = None self.encoding: str = 'utf-8' def _reprInternal(self): @@ -1550,7 +1551,7 @@ class MuseDataWork(prebase.ProtoM21Object): A work might consist of one or more files. ''' - def __init__(self): + def __init__(self) -> None: self.files: list[MuseDataFile] = [] self.encoding: str = 'utf-8' diff --git a/music21/musedata/translate.py b/music21/musedata/translate.py index e0184451cb..28b624078a 100644 --- a/music21/musedata/translate.py +++ b/music21/musedata/translate.py @@ -94,7 +94,7 @@ def _musedataRecordListToNoteOrChord(records, previousElement=None): post.pitch = records[0].getPitchObject() else: # environLocal.printDebug(['attempting chord creation: records', len(records)]) - # can supply a lost of Pitch objects at creation + # can supply a list of Pitch objects at creation post = chord.Chord([r.getPitchObject() for r in records]) # if a chord, we are assuming that all durations are the same diff --git a/music21/repeat.py b/music21/repeat.py index 8843da337b..903207ab64 100644 --- a/music21/repeat.py +++ b/music21/repeat.py @@ -93,7 +93,7 @@ def __init__(self, **keywords): super().__init__(**keywords) # store a text version of this expression self._textExpression = None - # store a lost of alternative text representations + # store a list of alternative text representations self._textAlternatives = [] # store a default text justification self.style.justify = 'center' diff --git a/music21/scale/__init__.py b/music21/scale/__init__.py index ad20ef311a..0c7d0d61fe 100644 --- a/music21/scale/__init__.py +++ b/music21/scale/__init__.py @@ -1537,7 +1537,7 @@ def tuneOnePitch(p, dst: list[pitch.Pitch]): for e in streamObj.recurse().notes: # get notes and chords if e.isChord: elementPitches = e.pitches - else: # simulate a lost + else: # simulate a list elementPitches = [e.pitch] # store a list of reset chord pitches diff --git a/music21/scale/test_intervalNetwork.py b/music21/scale/test_intervalNetwork.py index b9d4c11f85..6afac25d3a 100644 --- a/music21/scale/test_intervalNetwork.py +++ b/music21/scale/test_intervalNetwork.py @@ -234,7 +234,7 @@ def testBasicA(self): '[(5, Terminus.HIGH), (Terminus.HIGH, 5)]' ) - # in calling get next, get a lost of edges and a lost of nodes that all + # in calling get next, get a list of edges and a list of nodes that all # describe possible pathways self.assertEqual( net.getNext(net.nodes[Terminus.LOW], Direction.ASCENDING), diff --git a/music21/stream/tests.py b/music21/stream/tests.py index adb2633651..8c336783d5 100644 --- a/music21/stream/tests.py +++ b/music21/stream/tests.py @@ -3768,7 +3768,7 @@ def procCompare(mf_inner, match_inner): n = note.Note('g#3') n.quarterLength = 0.5 s.repeatAppend(n, 6) - # post = s.midiTracks # get a lost + # post = s.midiTracks # a list post = midiTranslate.streamHierarchyToMidiTracks(s) self.assertEqual(len(post[1].events), 30)