Wednesday, February 3, 2021

Music21 v6.7 released

music21 v6.7 is released. This will likely be the last release on the v6 line (more later), which has seen remarkable speed and stability improvements. Here’s what’s new in the past month since 6.5 came out:

  • Important bug fix: if you’ve had trouble loading music21 with an “importlib” error, this is fixed.
  • Composite lyrics changes to the implementation in 6.5: multiple syllables on one note in a single verse (like in Italian, “Il bianco edolce cigno”) now are imported to MusicXML property, stored in a Lyric.components object, and export to MusicXML properly.
  • Lyrics searching finds all lyrics in all verses (and composite lyrics too)
  • More major improvements to piano staff imports (thanks to Jacob Tyler Walls = JTW)
  • RomanNumeral.isMixture() shows whether a chord is borrowed from the other mode (Mark Gotham)
  • Several improvements in chord symbols (JTW + Alexandre Papadopoulos)
  • More improvements to finding instrument names from MIDI (JTW)
  • Duration marks in chords in ABC import properly (Marian Schultz)
  • Documentation improvements.
  • MusicXML parse failures now more often give the part and measure context (JTW)
  • Substantial bug fixes in Stream.setElementOffset. Adds a new Stream.coreSetElementOffset for the dangerous but super fast version, and makes the original version safer. (JTW)
  • Bug fixes in MEI articulations (heinzer) and accidentals (JTW)
  • Bug fixes in external tools in windows including spaces (JTW)
  • Channels handle better in MIDI (bearpelican)
  • Humdrum files with positioned rests no longer crash (Phil Kirlin)
  • OctaveRepeatingScale and CyclicalScale now usable as abstract classes (JTW)
  • Articulations and expressions musicxml does not support are exported as (JTW)
  • Better support for .musicxml as a file name within compressed .mxl files.
  • Beaming in pickup measures is fixed.
  • Stem directions can now be set automatically to coincide with beam groups. This is very useful if you are creating your own notation from scratch (as in VexFlow output; m21j gets the same routines)
  • Spanner endHeight and startHeight are processed correctly (JTW)
  • NoChord objects (in Chord Symbols) now retain their text (like “N.C.”) in more situations (JTW)
  • All NotRest objects get a .pitches function – a small thing, but will be helpful in the future.

6.7 is likely the last release in version 6. We begin work on version 7 today! This means that most deprecated functions will be removed, to speed up the system and help build new things.

  • Version 7 will require Python 3.7 as a minimum version. Python 3.6 will be end-of-life by November, and v.7 will last for at least into 2022. music21 will continue to support all Python versions that are actively maintained during the expected life of the version. v3.7-3.9 will be supported, and when 3.10 comes out, the next minor version of music21 will support it.

But dropping Py3.6 means some great changes:

  • Many things that are NamedTuples will become dataclasses. (all but sortTuple). This will make working with a lot of data much better.
  • Many many string options (such as notehead and beam types) will become Enums. This will help with avoiding making coding mistakes that are hard to detect. Where this has already happened (like in VoiceLeadingQuartet.MotionType) life has already become better. They will be StringEnums, and have a transition period, so code that checks for Beam.type == “start” or Lyric.syllabic == “begin” will still work (but I can never remember which is start and which is begin. Hence the point!)
  • Substantial changes to Unpitched to make percussion support work.
  • Some OrderedDicts (yuk!) will become normal dictionaries, now that insertion order is guaranteed to be preserved.
  • Whatever else has been annoying me but I haven't been able to fix by committing to keep major versions backwards compatible.
  • For simplifying the life of beginner users, __getattr__ and __dir__ will be defined for certain key modules (like Note) so that all the typing and internal information isn't exposed.
  • I'm hoping that getElementsByClass will be able to specify its return type, at least when called with a class. For people using Typing in Python, this will be a major improvement.

Deprecated functions gone ASAP:

  • Chord.findRoot() -- just use chord.root() instead
  • interval.convertSpecifier – use parseSpecifier instead
  • formats.findFormat (and many others in the formats module etc.)
  • humdrum.parseData, humdrum.parseFile (just use converter.parse)
  • Editorial.misc (just stick it on editorial)
  • Duration.updateQuarterLength (not needed)

New deprecations

  • SpacerRest will become deprecated – just use a normal Rest with hideObjectOnPrint = True
  • Setting a pitch.accidental to a number or string will be deprecated – create an Accidental object first
  • setElementOffset deprecates two keywords: addElement and setActiveSite
  • isClassOrSubclass to be deprecated, use Class in .classSet – WAY faster
  • getClefs to be deprecated – use recurse().getElementsByClass(‘Clef’)
  • getKeySignatures to be deprecated -- use recurse().getElementsByClass(‘KeySignature’)
  • Stream.makeChords() to be deprecated – Chordify is the way to go.
  • Stream.extendDurationsAndGetBoundaries – was meant to be deprecated in 6 and gone in 7. It gets a one version reprieve.
  • stripTies.retainContainers to be deprecated – will always be True. Just call .flat afterwards to not get this.
  • Stream.iter.variants to be deprecated. Just use .getElementsByClass(‘Variant’)
  • tree.toStream.chordified() to be deprecated. It’s the internal guts of Chordify now
  • VoiceLeading.color to be deprecated – set .style.color on notes like any other object

Weird changes of properties to methods:

  • Stream.iter() will be the encouraged new form instead of Stream.iter
  • Stream.sorted() will be encouraged new form instead of Stream.sorted
  • (This might not happen, but...) Stream.flat() encouraged for Stream.flat -- similarly for .semiFlat
  • Other properties where it is possible to encourage method calling will also get this change.

These methods were disguised as properties early on in music21 and it was a bad mistake, leading to lots of problems with introspection. Migration will go like this: v7 -- new forms are allowed and documentation is updated to encourage it. v8 -- all mention of old forms will be removed from the system and where possible using the old form will send a DeprecationWarning. v9 -- old forms are removed.

Version 7 might take until the summer or beyond. (Hence there may be bug-fix versions of v6.7 along the way). So for now, enjoy what’s out there and look forward to the future. The main branch will move to v7 but will remain as stable as possible.

Thanks to the community for great support and as always to the Seaver Institute, National Endowment for the Humanities, and MIT for support of music21.