Adding checks if music21 is installed

Music21 is optional dependency
This commit is contained in:
2023-03-18 00:01:48 +02:00
parent 5d122a90e0
commit f0b9de0118

View File

@ -1,10 +1,18 @@
"""Collection of converters""" """Collection of converters"""
from music21 import converter, note, stream, meter, chord, environment
from ziffers import zparse, Ziffers, Pitch, Rest, Chord from ziffers import zparse, Ziffers, Pitch, Rest, Chord
try:
from music21 import converter, note, stream, meter, chord, environment
music21_imported: bool = True
except ImportError:
music21_imported: bool = False
def to_music21(expression: str | Ziffers, **options): def to_music21(expression: str | Ziffers, **options):
"""Helper for passing options to the parser""" """Helper for passing options to the parser"""
if not music21_imported:
raise ImportError("Install Music21 library")
converter.registerSubconverter(ZiffersMusic21) converter.registerSubconverter(ZiffersMusic21)
if isinstance(expression, Ziffers): if isinstance(expression, Ziffers):
@ -32,40 +40,44 @@ def set_musescore_path(path: str):
settings["musescoreDirectPNGPath"] = path settings["musescoreDirectPNGPath"] = path
class ZiffersMusic21(converter.subConverters.SubConverter): if music21_imported:
"""Ziffers converter to Music21"""
registerFormats = ("ziffers",) # pylint: disable=locally-disabled, invalid-name, unused-argument, attribute-defined-outside-init
registerInputExtensions = ("zf",) class ZiffersMusic21(converter.subConverters.SubConverter):
"""Ziffers converter to Music21"""
def parseData(self, dataString, number=None): registerFormats = ("ziffers",)
"""Parses Ziffers string to Music21 object""" registerInputExtensions = ("zf",)
# Look for options in keywords object
keywords = self.keywords["keywords"] def parseData(self, dataString, number=None):
if "ziffers" in keywords: """Parses Ziffers string to Music21 object"""
options = keywords["ziffers"] # Look for options in keywords object
if "preparsed" in options: keywords = self.keywords["keywords"]
parsed = options["preparsed"] if "ziffers" in keywords:
options = keywords["ziffers"]
if "preparsed" in options:
parsed = options["preparsed"]
else:
parsed = zparse(dataString, **options)
else: else:
parsed = zparse(dataString, **options) parsed = zparse(dataString)
else:
parsed = zparse(dataString)
note_stream = stream.Part() note_stream = stream.Part()
if "time" in options: if "time" in options:
m_item = meter.TimeSignature(options["time"]) # Common time m_item = meter.TimeSignature(options["time"]) # Common time
else: else:
m_item = meter.TimeSignature("c") # Common time m_item = meter.TimeSignature("c") # Common time
note_stream.insert(0, m_item) note_stream.insert(0, m_item)
for item in parsed: for item in parsed:
if isinstance(item, Pitch): if isinstance(item, Pitch):
m_item = note.Note(item.note) m_item = note.Note(item.note)
m_item.duration.quarterLength = item.duration * 4 m_item.duration.quarterLength = item.duration * 4
elif isinstance(item, Rest): elif isinstance(item, Rest):
m_item = note.Rest(item.duration * 4) m_item = note.Rest(item.duration * 4)
elif isinstance(item, Chord): elif isinstance(item, Chord):
m_item = chord.Chord(item.notes) m_item = chord.Chord(item.notes)
m_item.duration.quarterLength = item.duration * 4 m_item.duration.quarterLength = item.duration * 4
note_stream.append(m_item) note_stream.append(m_item)
self.stream = note_stream.makeMeasures() # TODO: Is this ok?
self.stream = note_stream.makeMeasures()