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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions music21/abcFormat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1768,7 +1768,11 @@ def __init__(self, src: str = ''):
# store a list of component objects
self.subTokens: list[ABCToken] = []

def parse(self, forceKeySignature=None, forceDefaultQuarterLength=None):
def parse(
self,
forceDefaultQuarterLength: float|None = None,
forceKeySignature: key.KeySignature|None = None
):
'''
Handles the following types of chords:

Expand Down Expand Up @@ -1803,6 +1807,7 @@ def parse(self, forceKeySignature=None, forceDefaultQuarterLength=None):
outer_lengthModifier = self.getQuarterLength(outerLengthModifierStr,
forceDefaultQuarterLength=1.0)

activeKeySignature: key.KeySignature|None
if forceKeySignature is not None:
activeKeySignature = forceKeySignature
else: # may be None
Expand All @@ -1815,7 +1820,7 @@ def parse(self, forceKeySignature=None, forceDefaultQuarterLength=None):
# may need to supply key?
ah.tokenize(tokenStr)

inner_quarterLength = 0
inner_quarterLength: OffsetQL = 0.0
# tokens contained here are each ABCNote instances
for token in ah.tokens:
# environLocal.printDebug(['ABCChord: subTokens', t])
Expand Down Expand Up @@ -2631,10 +2636,10 @@ def tokenProcess(self) -> None:
# notes within slur marks need to be added to the spanner
if isinstance(token, ABCSlurStart):
token.fillSlur()
slurObj = token.slurObj
if t.TYPE_CHECKING:
assert token.slurObj is not None

self.activeSpanners.append(token.slurObj)
assert slurObj is not None
self.activeSpanners.append(slurObj)
self.activeParens.append('Slur')
elif isinstance(token, ABCParenStop):
if self.activeParens:
Expand Down Expand Up @@ -2951,10 +2956,10 @@ def definesMeasures(self):
Returns True if this token structure defines Measures in a normal Measure form.
Otherwise False

>>> abcStr = ('M:6/8\\nL:1/8\\nK:G\\nV:1 name="Whistle" ' +
... 'snm="wh"\\nB3 A3 | G6 | B3 A3 | G6 ||\\nV:2 name="violin" ' +
... 'snm="v"\\nBdB AcA | GAG D3 | BdB AcA | GAG D6 ||\\nV:3 name="Bass" ' +
... 'snm="b" clef=bass\\nD3 D3 | D6 | D3 D3 | D6 ||')
>>> abcStr = ('M:6/8\\nL:1/8\\nK:G\\nV:1 name="Whistle" '
... 'snm="wh"\\nB3 A3 | G6 | B3 A3 | G6 ||\\nV:2 name="violin" '
... 'snm="v"\\nBdB AcA | GAG D3 | BdB AcA | GAG D6 ||\\nV:3 name="Bass" '
... 'snm="b" clef=bass\\nD3 D3 | D6 | D3 D3 | D6 ||')
>>> ah = abcFormat.ABCHandler()
>>> junk = ah.process(abcStr)
>>> ah.definesMeasures()
Expand Down Expand Up @@ -2989,10 +2994,10 @@ def splitByVoice(self) -> list[ABCHandler]:

Each part is returned as a ABCHandler instance.

>>> abcStr = ('M:6/8\\nL:1/8\\nK:G\\nV:1 name="Whistle" ' +
... 'snm="wh"\\nB3 A3 | G6 | B3 A3 | G6 ||\\nV:2 name="violin" ' +
... 'snm="v"\\nBdB AcA | GAG D3 | BdB AcA | GAG D6 ||\\nV:3 name="Bass" ' +
... 'snm="b" clef=bass\\nD3 D3 | D6 | D3 D3 | D6 ||')
>>> abcStr = ('M:6/8\\nL:1/8\\nK:G\\nV:1 name="Whistle" '
... 'snm="wh"\\nB3 A3 | G6 | B3 A3 | G6 ||\\nV:2 name="violin" '
... 'snm="v"\\nBdB AcA | GAG D3 | BdB AcA | GAG D6 ||\\nV:3 name="Bass" '
... 'snm="b" clef=bass\\nD3 D3 | D6 | D3 D3 | D6 ||')
>>> ah = abcFormat.ABCHandler()
>>> ah.process(abcStr)
>>> tokenColls = ah.splitByVoice()
Expand Down
4 changes: 2 additions & 2 deletions music21/alpha/analysis/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ def findConsecutiveScale(source, targetScale, degreesRequired=5,
stepSize=1,
comparisonAttribute=comparisonAttribute):
pass
# environLocal.printDebug(['matched degree count but next pitch is ' +
# 'in scale and direction', 'collDegrees', collDegrees])
# environLocal.printDebug(['matched degree count but next pitch is '
# + 'in scale and direction', 'collDegrees', collDegrees])
else:
# environLocal.printDebug(['matched degree count', 'collDegrees', collDegrees,
# 'pNext', pNext])
Expand Down
9 changes: 4 additions & 5 deletions music21/analysis/reduction.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,11 +615,10 @@ def _createEventSpans(self):
# eLast = partMeasures[0][i]
# # use duration, not barDuration.quarterLength
# # as want filled duration?
# eEnd = (eLast.getOffsetBySite(
# partMeasures[0]) +
# eLast.barDuration.quarterLength)
# ds = {'eStart':eStart, 'span':eEnd-eStart,
# 'weight':None, 'color':pColor}
# eEnd = (eLast.getOffsetBySite(partMeasures[0])
# + eLast.barDuration.quarterLength)
# ds = {'eStart': eStart, 'span': eEnd - eStart,
# 'weight': None, 'color': pColor}
# dataEvents.append(ds)
# eStart = None
# eLast = partMeasures[0][i]
Expand Down
4 changes: 2 additions & 2 deletions music21/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2447,8 +2447,8 @@ def _setActiveSite(self, site: stream.Stream|None):
self._activeSiteStoredOffset = storedOffset
# siteId = id(site)
# if not self.sites.hasSiteId(siteId): # This should raise a warning, should not happen
# # environLocal.warn('Adding a siteDict entry for a ' +
# # 'site that should already be there!')
# # environLocal.warn('Adding a siteDict entry for a '
# # 'site that should already be there!')
# self.sites.add(site, idKey=siteId)
else:
self._activeSiteStoredOffset = None
Expand Down
6 changes: 3 additions & 3 deletions music21/capella/fromCapellaXML.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def domElementFromText(self, xmlText=None):

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> funnyTag = ci.domElementFromText(
... '<funny yes="definitely"><greg/>hi<greg><ha>ha</ha>' +
... '<funny yes="definitely"><greg/>hi<greg><ha>ha</ha>'
... '<greg type="embedded"/></greg></funny>')
>>> funnyTag
<Element 'funny' at 0x...>
Expand Down Expand Up @@ -441,7 +441,7 @@ def chordOrNoteFromChord(self, chordElement):
This one is an actual chord

>>> chordElement = ci.domElementFromText(
... '<chord><duration base="1/8"/>' +
... '<chord><duration base="1/8"/>'
... '<heads><head pitch="G4"/><head pitch="A5"/></heads></chord>')
>>> c = ci.chordOrNoteFromChord(chordElement)
>>> c
Expand Down Expand Up @@ -615,7 +615,7 @@ def lyricListFromLyric(self, lyricElement):

>>> ci = capella.fromCapellaXML.CapellaImporter()
>>> lyricEl = ci.domElementFromText(
... '<lyric><verse i="0" hyphen="true">di</verse>' +
... '<lyric><verse i="0" hyphen="true">di</verse>'
... '<verse i="1">man,</verse><verse i="2">frau,</verse></lyric>')
>>> ci.lyricListFromLyric(lyricEl)
[<music21.note.Lyric number=1 syllabic=begin text='di'>,
Expand Down
6 changes: 3 additions & 3 deletions music21/converter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ def parseURL(
re-reading from a cached file.

>>> joplinURL = ('https://github.com/cuthbertLab/music21/raw/master'
... + '/music21/corpus/joplin/maple_leaf_rag.mxl')
... '/music21/corpus/joplin/maple_leaf_rag.mxl')
>>> c = converter.Converter()
>>> #_DOCS_SHOW c.parseURL(joplinURL)
>>> #_DOCS_SHOW joplinStream = c.stream
Expand Down Expand Up @@ -2130,8 +2130,8 @@ def testMEIvsMX(self):
# These strings aren't valid documents, but they are enough to pass the detection we're
# testing in parseData(). But it does mean we'll be testing in a strange way.
meiString = '<?xml version="1.0" encoding="UTF-8"?><mei><note/></mei>'
# mxlString = ('<?xml version="1.0" encoding="UTF-8"?>' +
# '<score-partwise><note/></score-partwise>')
# mxlString = ('<?xml version="1.0" encoding="UTF-8"?>'
# '<score-partwise><note/></score-partwise>')

# The "mei" module raises an MeiElementError with "meiString," so as long as that's raised,
# we know that parseData() chose correctly.
Expand Down
8 changes: 4 additions & 4 deletions music21/converter/subConverters.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,8 +631,8 @@ def parseData(self, humdrumString, number=None):
Open Humdrum data from a string -- calls
:meth:`~music21.humdrum.spineParser.HumdrumDataCollection.parse()`.

>>> humData = ('**kern\\n*M2/4\\n=1\\n24r\\n24g#\\n24f#\\n24e\\n24c#\\n' +
... '24f\\n24r\\n24dn\\n24e-\\n24gn\\n24e-\\n24dn\\n*-')
>>> humData = ('**kern\\n*M2/4\\n=1\\n24r\\n24g#\\n24f#\\n24e\\n24c#\\n'
... '24f\\n24r\\n24dn\\n24e-\\n24gn\\n24e-\\n24dn\\n*-')
>>> c = converter.subConverters.ConverterHumdrum()
>>> s = c.parseData(humData)
>>> c.stream.show('text')
Expand Down Expand Up @@ -762,8 +762,8 @@ def parseData(self, nwcData):
r'''
Open Noteworthy data from a string or list

>>> nwcData = ('!NoteWorthyComposer(2.0)\n|AddStaff\n|Clef|' +
... 'Type:Treble\n|Note|Dur:Whole|Pos:1^')
>>> nwcData = ('!NoteWorthyComposer(2.0)\n|AddStaff\n|Clef|'
... 'Type:Treble\n|Note|Dur:Whole|Pos:1^')
>>> c = converter.subConverters.ConverterNoteworthy()
>>> c.parseData(nwcData)
>>> c.stream.show('text')
Expand Down
4 changes: 2 additions & 2 deletions music21/corpus/testCorpus.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ def testSearch10(self):
# self.assertGreater(len(searchResults), 0)
# # returns items in pairs: url and work number
# self.assertEqual(searchResults[0].sourcePath,
# 'http://impromastering.com/uploads/transcription_file/' +
# 'file/196/Giant_Steps__John_Coltrane_C.xml')
# 'http://impromastering.com/uploads/transcription_file/'
# + 'file/196/Giant_Steps__John_Coltrane_C.xml')

# def testGetWorkList(self):
# self.assertGreaterEqual(len(corpus.corpora.CoreCorpus().getPaths('.md')), 38)
Expand Down
32 changes: 18 additions & 14 deletions music21/harmony.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ def _updateFromParameters(
but we want the objects to retain their initial root, bass, and inversion.
'''
if root and isinstance(root, str):
root = common.cleanedFlatNotation(root)
self.root(pitch.Pitch(root, octave=3))
root_str = common.cleanedFlatNotation(root)
self.root(pitch.Pitch(root_str, octave=3))
elif root is not None:
self.root(root)

Expand All @@ -308,8 +308,8 @@ def _updateFromParameters(

# and then bass.
if bass and isinstance(bass, str):
bass = common.cleanedFlatNotation(bass)
self.bass(pitch.Pitch(bass, octave=3), allow_add=True)
bass_str = common.cleanedFlatNotation(bass)
self.bass(pitch.Pitch(bass_str, octave=3), allow_add=True)
elif bass is not None:
self.bass(bass, allow_add=True)

Expand Down Expand Up @@ -2267,9 +2267,9 @@ def findFigure(self):
>>> from xml.etree.ElementTree import fromstring as EL
>>> MP = musicxml.xmlToM21.MeasureParser()

>>> elStr = (r'<harmony><root><root-step>C</root-step></root><kind>dominant</kind>' +
... '<degree><degree-value>9</degree-value><degree-alter>-1</degree-alter>' +
... ' <degree-type>add</degree-type></degree></harmony>')
>>> elStr = ('<harmony><root><root-step>C</root-step></root><kind>dominant</kind>'
... '<degree><degree-value>9</degree-value><degree-alter>-1</degree-alter>'
... ' <degree-type>add</degree-type></degree></harmony>')
>>> mxHarmony = EL(elStr)

>>> cs = MP.xmlToChordSymbol(mxHarmony)
Expand All @@ -2283,10 +2283,10 @@ def findFigure(self):
<music21.pitch.Pitch B-3>,
<music21.pitch.Pitch D-4>)

>>> elStr = (r'<harmony><root><root-step>C</root-step></root><kind>major</kind>' +
... '<bass><bass-step>B</bass-step><bass-alter>-1</bass-alter></bass>' +
... '<degree><degree-value>2</degree-value><degree-alter>0</degree-alter>' +
... ' <degree-type>add</degree-type></degree></harmony>')
>>> elStr = ('<harmony><root><root-step>C</root-step></root><kind>major</kind>'
... '<bass><bass-step>B</bass-step><bass-alter>-1</bass-alter></bass>'
... '<degree><degree-value>2</degree-value><degree-alter>0</degree-alter>'
... ' <degree-type>add</degree-type></degree></harmony>')
>>> mxHarmony = EL(elStr)

>>> cs = MP.xmlToChordSymbol(mxHarmony)
Expand Down Expand Up @@ -2682,8 +2682,13 @@ def testHarmonyPreservesInversionAndBass(self):
self.assertEqual(explicitFm6.inversion(), 1)
self.assertEqual(explicitFm6.bass(find=False).name, 'A-')
self.assertEqual(explicitFm6.root(find=False).name, 'F')
self.assertLess(explicitFm6.bass(find=False).octave,
explicitFm6.root(find=False).octave)
fm6bassOctave = explicitFm6.bass(find=False).octave
fm6rootOctave = explicitFm6.root(find=False).octave
self.assertIsNotNone(fm6bassOctave)
self.assertIsNotNone(fm6rootOctave)
assert fm6bassOctave is not None
assert fm6rootOctave is not None
self.assertLess(fm6bassOctave, fm6rootOctave)

def testClassSortOrderHarmony(self):
'''
Expand Down Expand Up @@ -2836,7 +2841,6 @@ def runTestOnChord(self, xmlString, figure, pitches):
self.assertEqual(cs1.bass(), cs3.bass())

def testChordWithBass(self):

xmlString = '''
<harmony>
<root>
Expand Down
24 changes: 12 additions & 12 deletions music21/humdrum/spineParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,10 @@ def parseEventListFromDataStream(

Returns eventList in addition to setting it as `self.eventList`.

>>> eventString = ('!!! COM: Beethoven, Ludwig van\n' +
... '!! Not really a piece by Beethoven\n' +
... '**kern\t**dynam\n' +
... 'C4\tpp\n' +
>>> eventString = ('!!! COM: Beethoven, Ludwig van\n'
... '!! Not really a piece by Beethoven\n'
... '**kern\t**dynam\n'
... 'C4\tpp\n'
... 'D8\t.\n')
>>> hdc = humdrum.spineParser.HumdrumDataCollection(eventString)
>>> hdc.maxSpines = 2
Expand Down Expand Up @@ -459,10 +459,10 @@ def parseProtoSpinesAndEventCollections(
Returns a tuple of protoSpines and eventCollections in addition to
setting it in the calling object.

>>> eventString = ('!!!COM: Beethoven, Ludwig van\n' +
... '!! Not really a piece by Beethoven\n' +
... '**kern\t**dynam\n' +
... 'C4\tpp\n' +
>>> eventString = ('!!!COM: Beethoven, Ludwig van\n'
... '!! Not really a piece by Beethoven\n'
... '**kern\t**dynam\n'
... 'C4\tpp\n'
... 'D8\t.\n')
>>> hdc = humdrum.spineParser.HumdrumDataCollection(eventString)
>>> hdc.maxSpines = 2
Expand Down Expand Up @@ -784,11 +784,11 @@ def insertGlobalEvents(self) -> None:
# 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. Is this your problem? ' +
# '(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 does not have ' +
# 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()
Expand Down Expand Up @@ -2400,7 +2400,7 @@ def hdStringToNote(contents: str) -> note.GeneralNote:
elif '\\' in contents:
thisObject.stemDirection = 'down'

# 3.2.7 Duration +
# 3.2.7 Duration and
# 3.2.8 N-Tuplets

# TODO: SPEEDUP -- only search for rational after foundNumber.
Expand Down
2 changes: 1 addition & 1 deletion music21/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ def autoAssignMidiChannel(self, usedChannels: list[int], maxMidi=16):
self.midiChannel = ch
return self.midiChannel
return 0
# raise InstrumentException('we are out of midi channels and this ' +
# raise InstrumentException('we are out of midi channels and this '
# 'was not already detected PROGRAM BUG!')


Expand Down
2 changes: 1 addition & 1 deletion music21/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -3492,7 +3492,7 @@ def _diatonicTransposePitch(self,
# pitchAlt = copy.deepcopy(pitch2)
# pitchAlt.ps = pitch2.ps + halfStepsToFix
# environLocal.printDebug(
# 'coercing pitch due to a transposition that requires an extreme ' +
# 'coercing pitch due to a transposition that requires an extreme '
# f'accidental: {pitch2} -> {pitchAlt}')
# pitch2 = pitchAlt
pitch2.ps = pitch2.ps + halfStepsToFix
Expand Down
4 changes: 2 additions & 2 deletions music21/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -999,8 +999,8 @@ def getPositionForStaff(self, pageId, systemId, staffId):
>>> ls.getPositionForStaff(1, 0, 0)
(0.0, 40.0)
The second staff (staff 1) begins at the end of staff 0 (40.0) +
the appropriate staffDistance
The second staff (staff 1) begins at the end of
staff 0 (40.0) plus the appropriate staffDistance
and adds the height of the staff. Staff 1 here has a size of 80 which means
80% of the normal staff size. 40 * 0.8 = 32.0:
Expand Down
4 changes: 2 additions & 2 deletions music21/mei/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,8 @@ def allPartsPresent(scoreElem) -> tuple[str, ...]:
... <!-- ... some music ... -->
... </section>
... </score>"""
>>> import xml.etree.ElementTree as ETree
>>> meiDoc = ETree.fromstring(meiDoc)
>>> from xml.etree.ElementTree import fromstring as EL
>>> meiDoc = EL(meiDoc)
>>> mei.base.allPartsPresent(meiDoc)
('1', '2')
Expand Down
10 changes: 5 additions & 5 deletions music21/musedata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1592,11 +1592,11 @@ def addString(self, input_str):
Add a string representation acting like a part file
>>> mdw = musedata.MuseDataWork()
>>> mdw.addString('WK#:581 MV#:3c\nBreitkopf & Hartel, Vol. 13\n' +
... 'Clarinet Quintet\n' +
... 'Trio II\n' +
... '$ K:0 Q:6 T:3/4 X:-11 C:4\n' +
... 'C5 3 e d [ (&0p\n' +
>>> mdw.addString('WK#:581 MV#:3c\nBreitkopf & Hartel, Vol. 13\n'
... 'Clarinet Quintet\n'
... 'Trio II\n'
... '$ K:0 Q:6 T:3/4 X:-11 C:4\n'
... 'C5 3 e d [ (&0p\n'
... 'E5 3 e d ]')
# TODO: Okay, so what? did we test this or demo anything?
Expand Down
Loading
Loading