Skip to content
Merged
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
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
by the agent or author). Failure to do so may result in the user being banned from the project.
- Agents must follow the [Code of Conduct](CODE_OF_CONDUCT.md). Agents that do not will be banned as well at their users.
Not even the slightest bit of disrespect from an AI agent will be tolerated.
- Mark changes in public interface with `* Changed in v[X]: One-line explanation.` Or new features with "New" instead of "Changed".
- Changes to parsing formats (esp. musicxml) need to update the patch version of the version file.
- Music21 uses even minor version numbers for alpha/beta and odd minor numbers for releases.
- If the current version is MAJOR.0.... then mark `Changed in vMAJOR:` if it is `MAJOR.[even]` use the next odd number, like if it's 10.2 now use "Changed in 10.3". If current version is odd that's likely a mistake or you caught it just before a new release. Use the following odd number instead.

# Worktrees

Expand Down
2 changes: 1 addition & 1 deletion music21/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
'''
from __future__ import annotations

__version__ = '10.1.0'
__version__ = '10.2.0b1'

def get_version_tuple(vv):
v = vv.split('.')
Expand Down
6 changes: 3 additions & 3 deletions music21/abcFormat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def stripComment(strSrc: str) -> str:
>>> abcFormat.ABCToken.stripComment('b1 % a b-flat actually')
'b1 '

* Changed in v6.2: made a staticmethod
* Changed in v6.2: made a staticmethod.
'''
if '%' in strSrc:
return strSrc.split('%')[0]
Expand Down Expand Up @@ -1860,7 +1860,7 @@ class ABCHandler:
define new phrases. This is useful for parsing extra information from
the Essen Folksong repertory

* New in v6.3: lineBreaksDefinePhrases -- does not yet do anything
* New in v6.3: lineBreaksDefinePhrases -- does not yet do anything.
'''
def __init__(self,
abcVersion: tuple[int, ...] = defaults.abcVersionDefault,
Expand Down Expand Up @@ -2041,7 +2041,7 @@ def parseHeaderForVersionInformation(self, inputSearch: str) -> None:
>>> ah.abcVersion
(2, 3, 2)

Changed in v9: abcVersion defaults to (1, 3, 0) as documented.
* Changed in v9: abcVersion defaults to (1, 3, 0) as documented.
'''
verMats = reAbcVersion.search(inputSearch)
if verMats:
Expand Down
18 changes: 8 additions & 10 deletions music21/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<class 'music21.base.Music21Object'>

>>> music21.VERSION_STR
'10.1.0'
'10.2.0b1'

Alternatively, after doing a complete import, these classes are available
under the module "base":
Expand Down Expand Up @@ -1570,7 +1570,7 @@ class name:
and `priorityTargetOnly=True`.

* Changed in v5.7: added followDerivation=False and made
everything but the class keyword only
everything but the class keyword only.
* New in v6: added priorityTargetOnly -- see contextSites for description.
* New in v7: added getElementMethod `all` and `ElementSearch` enum.
* Changed in v8: class-based calls return properly typed items. Putting
Expand Down Expand Up @@ -2288,7 +2288,7 @@ def next(self,
<music21.note.Note F#> <music21.stream.Part Soprano>
<music21.bar.Barline type=final> <music21.stream.Part Soprano>

* Changed in v6: added activeSiteOnly -- see description in `.contextSites()`
* Changed in v6: added activeSiteOnly -- see description in `.contextSites()`.
'''
allSiteContexts = list(self.contextSites(
returnSortTuples=True,
Expand Down Expand Up @@ -2375,7 +2375,7 @@ def previous(self,
<music21.metadata.Metadata object at 0x11116d080>
<music21.stream.Score bach/bwv66.6.mxl>

* Changed in v6: added activeSiteOnly -- see description in `.contextSites()`
* Changed in v6: added activeSiteOnly -- see description in `.contextSites()`.
'''
# allSiteContexts = list(self.contextSites(returnSortTuples=True))
# maxRecurse = 20
Expand Down Expand Up @@ -3068,7 +3068,7 @@ def containerHierarchy(
<music21.stream.Part newPart>]

* Changed in v5.7: `followDerivation` and
`includeNonStreamDerivations` are now keyword only
`includeNonStreamDerivations` are now keyword only.
'''
post = []
focus = self
Expand Down Expand Up @@ -3212,7 +3212,7 @@ def splitAtQuarterLength(
music21.duration.DurationException: cannot split a duration (0.5)
at this quarterLength (7/10)

* Changed in v7: all but quarterLength are keyword only
* Changed in v7: all but quarterLength are keyword only.
'''
from music21 import chord
from music21 import note
Expand Down Expand Up @@ -3764,8 +3764,7 @@ def beat(self) -> fractions.Fraction|float:
>>> math.isnan(isolatedNote.beat)
True

* Changed in v6.3: returns `nan` if
there is no TimeSignature in sites.
* Changed in v6.3: returns `nan` if there is no TimeSignature in sites.
Previously raised an exception.
'''
try:
Expand Down Expand Up @@ -3807,8 +3806,7 @@ def beatStr(self) -> str:
>>> isolatedNote.beatStr
'nan'

* Changed in v6.3: returns 'nan' if
there is no TimeSignature in sites.
* Changed in v6.3: returns 'nan' if there is no TimeSignature in sites.
Previously raised an exception.
'''
try:
Expand Down
24 changes: 12 additions & 12 deletions music21/chord/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def _add_core_or_init(self,

Also requires that notes be iterable.

Changed in v9: incorrect arguments raise TypeError
* Changed in v9: incorrect arguments raise TypeError.
'''
# quickDuration specifies whether the duration object for the chord
# should be taken from the first note of the list.
Expand Down Expand Up @@ -565,7 +565,7 @@ def setVolumes(self, volumes: Sequence['music21.volume.Volume'|int|float]):
>>> c.volume
<music21.volume.Volume realized=0.76>

* New in v8: replaces setting .volume to a list
* New in v8: replaces setting .volume to a list.
'''
# if setting components, remove single velocity
self._volume = None
Expand Down Expand Up @@ -2432,7 +2432,7 @@ def inversion(
sets the value to be returned later, which might be useful for
cases where the chords are poorly spelled, or there is an added note.

* Changed in v8: deal with chords without pitches
* Changed in v8: deal with chords without pitches.
'''
if not self.pitches:
return -1
Expand Down Expand Up @@ -2975,7 +2975,7 @@ def isFrenchAugmentedSixth(self, *, permitAnyInversion=False) -> bool:
>>> fr6c.isFrenchAugmentedSixth(permitAnyInversion=True)
True

* Changed in v7: `permitAnyInversion` added
* Changed in v7: `permitAnyInversion` added.

OMIT_FROM_DOCS

Expand Down Expand Up @@ -3020,7 +3020,7 @@ def isGermanAugmentedSixth(self, *, permitAnyInversion=False) -> bool:
>>> gr6c.isGermanAugmentedSixth(permitAnyInversion=True)
True

* Changed in v7: `permitAnyInversion` added
* Changed in v7: `permitAnyInversion` added.

OMIT_FROM_DOCS

Expand Down Expand Up @@ -3632,7 +3632,7 @@ def isSwissAugmentedSixth(self, *, permitAnyInversion=False):
>>> ch3.isSwissAugmentedSixth(permitAnyInversion=True)
True

* Changed in v7: `permitAnyInversion` added
* Changed in v7: `permitAnyInversion` added.
'''
return self._isAugmentedSixthHelper(
(4, 27, -1),
Expand Down Expand Up @@ -3947,7 +3947,7 @@ def root(self,
music21.chord.ChordException: no pitches in chord <music21.chord.Chord ...>

* Changed in v5.2: `find` is a keyword-only parameter,
`newroot` finds `Pitch` in `Chord`
`newroot` finds `Pitch` in `Chord`.
'''
# None value for find indicates: return override if overridden, cache if cached
# or find new value if neither is the case.
Expand Down Expand Up @@ -4878,7 +4878,7 @@ def commonName(self) -> str:
>>> chord.Chord('C4 E-4 G4 A#4 D4').commonName
'enharmonic equivalent to minor-ninth chord'

* Changed in v5.5: special cases for checking enharmonics in some cases
* Changed in v5.5: special cases for checking enharmonics in some cases.
* Changed in v6.5: better handling of 0-, 1-, and 2-pitchClass and microtonal chords.
* Changed in v7: Inversions of augmented sixth-chords are specified.
* Changed in v7.3: Enharmonic equivalents to common seventh and ninth chords are specified.
Expand Down Expand Up @@ -5374,7 +5374,7 @@ def notes(self) -> tuple[note.Note, ...]:
>>> c1
<music21.chord.Chord D#4 C#4>

* New in v5.7
* New in v5.7.
'''
return tuple(self._notes)

Expand Down Expand Up @@ -5940,7 +5940,7 @@ def scaleDegrees(self):
>>> chord.Chord('C4 E4 G4').scaleDegrees is None
True

* Changed in v6.5: will return `None` if no context can be found:
* Changed in v6.5: will return `None` if no context can be found.
'''
from music21 import scale
# roman numerals have this built in as the key attribute
Expand Down Expand Up @@ -5990,7 +5990,7 @@ def seventh(self):
>>> c.seventh
<music21.pitch.Pitch B#4>

* Changed in v6.5: return None on empty chords/errors
* Changed in v6.5: return `None` on empty chords/errors.

OMIT_FROM_DOCS

Expand All @@ -6015,7 +6015,7 @@ def third(self) -> pitch.Pitch|None:
>>> cMaj1stInv.third.octave
3

* Changed in v6.5: return `None` on empty chords/errors
* Changed in v6.5: return `None` on empty chords/errors.

OMIT_FROM_DOCS

Expand Down
3 changes: 1 addition & 2 deletions music21/clef.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,7 @@ class PercussionClef(Clef):
>>> pc.lowestLine == clef.TrebleClef().lowestLine
True

* Changed in v7.3: setting `octaveChange` no longer affects
`lowestLine`
* Changed in v7.3: setting `octaveChange` no longer affects `lowestLine`.
'''
_DOC_ATTR: dict[str, str] = {}

Expand Down
2 changes: 1 addition & 1 deletion music21/common/classTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def isIterable(usrData: t.Any) -> t.TypeGuard[Iterable]:
>>> common.isIterable(list)
False

* Changed in v7.3: Classes (not instances) are not iterable
* Changed in v7.3: Classes (not instances) are not iterable.
'''
if isinstance(usrData, (str, bytes)):
return False
Expand Down
2 changes: 1 addition & 1 deletion music21/common/numberTools.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ def opFrac(num: OffsetQLIn) -> OffsetQL:
0.0

* Changed in v9.3: opFrac(None) should not be called. If it is called,
it now returns 0.0
it now returns 0.0.
'''
# This is a performance critical operation, tuned to go as fast as possible.
# hence redundancy -- first we check for type (no inheritance) and then we
Expand Down
2 changes: 1 addition & 1 deletion music21/common/parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ def safeToParallize() -> bool:
Will return False if we are in a multiprocessing child process or if
there is only one CPU or if pytest's x-dist worker flag is in the environment.

* New in v10
* New in v10.
'''
return (
cpus() > 1
Expand Down
4 changes: 2 additions & 2 deletions music21/converter/subConverters.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ def getTemporaryFile(self, subformats: Iterable[str] = ()) -> pathlib.Path:
>>> import os #_DOCS_HIDE
>>> os.remove(tf) #_DOCS_HIDE

* Changed in v6: returns pathlib.Path
* Changed in v6: returns pathlib.Path.
'''
ext = self.getExtensionForSubformats(subformats)
fp = environLocal.getTempFile(ext, returnPathlib=True)
Expand Down Expand Up @@ -888,7 +888,7 @@ def writeDataStream(self,
Writes `dataStr` which must be bytes to `fp`.
Adds `.musicxml` suffix to `fp` if it does not already contain some suffix.

* Changed in v7: returns a pathlib.Path
* Changed in v7: returns a pathlib.Path.

OMIT_FROM_DOCS

Expand Down
2 changes: 1 addition & 1 deletion music21/corpus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ def parse(
>>> bachChorale.metadata.corpusFilePath
'bach/bwv66.6.mxl'

Changed in v9: corpusFilePath is stored in metadata and now has a capital 'P'
* Changed in v9: corpusFilePath is stored in metadata and now has a capital 'P'.
'''
return manager.parse(
workName=workName,
Expand Down
2 changes: 1 addition & 1 deletion music21/corpus/corpora.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def translateExtensions(
>>> coreCorpus.translateExtensions(('.mid', '.musicxml'))
('.mid', '.midi', '.xml', '.mxl', '.musicxml')

* Changed in v9: returns a tuple, not a list. first element must be an Iterable of strings
* Changed in v9: returns a tuple, not a list. First element must be an Iterable of strings.

TODO: unify with tools in common.formats
'''
Expand Down
2 changes: 1 addition & 1 deletion music21/duration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2460,7 +2460,7 @@ def _updateQuarterLength(self):
'''
Look to components and determine quarter length.

* Changed in v7: made private. And faster
* Changed in v7: made private and faster.
'''
if self.linked is False:
return
Expand Down
4 changes: 1 addition & 3 deletions music21/expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ def realize(
and a list of notes after the "main note".

* New in v8: inPlace boolean; note that some ornaments
might not return a Note in the second position at all (such as trills)
might not return a Note in the second position at all (such as trills),
so inPlace does nothing.
* Changed in v9: Optional keySig can be passed in (useful in cases where there
is no keySig in srcObj's context, or where a different keySig is desired).
Expand Down Expand Up @@ -1050,8 +1050,6 @@ class Mordent(GeneralMordent):
>>> mNotFlatWithKeyFromContext.getSize(noteB3)
<music21.interval.Interval M-2>



* Changed in v7: Mordent sizes are GenericIntervals -- as was originally
intended but programmed incorrectly.
* Changed in v9: Support an accidental on Mordent. This also adds the concept of
Expand Down
2 changes: 1 addition & 1 deletion music21/figuredBass/harmony.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class FiguredBass(Harmony):
>>> fb.pitches
()

* New in v9.3
* New in v9.3.
'''
def __init__(self,
figureString: str = '',
Expand Down
2 changes: 1 addition & 1 deletion music21/harmony.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ def addChordStepModification(self, degree, *, updatePitches=True):
>>> h.pitches
(<music21.pitch.Pitch C3>, <music21.pitch.Pitch E3>, <music21.pitch.Pitch G-3>)

* Changed in v7: updatePitches is True by default
* Changed in v7: updatePitches is True by default.
'''
if not isinstance(degree, ChordStepModification):
# TODO: possibly create ChordStepModification objects from other
Expand Down
12 changes: 6 additions & 6 deletions music21/humdrum/spineParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ class ProtoSpine(prebase.ProtoM21Object):
See :meth:`~music21.humdrum.spineParser.parseProtoSpinesAndEventCollections`
for more details on how ProtoSpine objects are created.

* Changed in v10: ProtoSpines now iterate over their eventLists and are ProtoM21Objects
* Changed in v10: ProtoSpines now iterate over their eventLists and are ProtoM21Objects.
'''

def __init__(self, eventList: list[SpineEvent|None]|None = None) -> None:
Expand Down Expand Up @@ -2165,7 +2165,7 @@ class EventCollection(prebase.ProtoM21Object):

In the future, EventCollection may enforce that all events have the same lineNumber

* New in v10: lineNumber
* New in v10: lineNumber.
'''
def __init__(self, maxSpines: int = 0, lineNumber: int = 0) -> None:
self.events: common.defaultlist = common.defaultlist(lambda: None)
Expand Down Expand Up @@ -2495,10 +2495,10 @@ def hdStringToMeasure(
kern uses an equals sign followed by processing instructions to
create new measures.

Changed in v10: repeat dots are encoded as :class:`~music21.bar.Repeat`
objects instead of being stuffed into a non-existent ``Barline.repeatDots``
attribute. ``:|:`` now produces an end-Repeat on the previous measure's
right barline AND a start-Repeat on the new measure's left barline.
* Changed in v10: repeat dots are encoded as :class:`~music21.bar.Repeat`
objects instead of being stuffed into a non-existent ``Barline.repeatDots``
attribute. ``:|:`` now produces an end-Repeat on the previous measure's
right barline AND a start-Repeat on the new measure's left barline.
'''
if contents == '==|':
environLocal.warn(
Expand Down
2 changes: 1 addition & 1 deletion music21/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -2425,7 +2425,7 @@ def fromString(instrumentString: str,
(an honorary 'language' for these purposes).

Alternatively, you can specify the language to search using the `language`
argument. (New in v7.3)
argument. (New in v7.3.)

>>> t12 = instrument.fromString('Klarinette', language=instrument.SearchLanguage.GERMAN)
>>> t12
Expand Down
Loading
Loading