From f0b9de01183d4a4eb9cd6ff7fb98cf4d37693b88 Mon Sep 17 00:00:00 2001 From: Miika Alonen Date: Sat, 18 Mar 2023 00:01:48 +0200 Subject: [PATCH] Adding checks if music21 is installed Music21 is optional dependency --- ziffers/converters.py | 78 +++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/ziffers/converters.py b/ziffers/converters.py index e9902c1..36b124a 100644 --- a/ziffers/converters.py +++ b/ziffers/converters.py @@ -1,10 +1,18 @@ """Collection of converters""" -from music21 import converter, note, stream, meter, chord, environment 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): """Helper for passing options to the parser""" + + if not music21_imported: + raise ImportError("Install Music21 library") + converter.registerSubconverter(ZiffersMusic21) if isinstance(expression, Ziffers): @@ -32,40 +40,44 @@ def set_musescore_path(path: str): settings["musescoreDirectPNGPath"] = path -class ZiffersMusic21(converter.subConverters.SubConverter): - """Ziffers converter to Music21""" +if music21_imported: - registerFormats = ("ziffers",) - registerInputExtensions = ("zf",) + # pylint: disable=locally-disabled, invalid-name, unused-argument, attribute-defined-outside-init + class ZiffersMusic21(converter.subConverters.SubConverter): + """Ziffers converter to Music21""" - def parseData(self, dataString, number=None): - """Parses Ziffers string to Music21 object""" - # Look for options in keywords object - keywords = self.keywords["keywords"] - if "ziffers" in keywords: - options = keywords["ziffers"] - if "preparsed" in options: - parsed = options["preparsed"] + registerFormats = ("ziffers",) + registerInputExtensions = ("zf",) + + def parseData(self, dataString, number=None): + """Parses Ziffers string to Music21 object""" + # Look for options in keywords object + keywords = self.keywords["keywords"] + if "ziffers" in keywords: + options = keywords["ziffers"] + if "preparsed" in options: + parsed = options["preparsed"] + else: + parsed = zparse(dataString, **options) else: - parsed = zparse(dataString, **options) - else: - parsed = zparse(dataString) + parsed = zparse(dataString) - note_stream = stream.Part() - if "time" in options: - m_item = meter.TimeSignature(options["time"]) # Common time - else: - m_item = meter.TimeSignature("c") # Common time + note_stream = stream.Part() + if "time" in options: + m_item = meter.TimeSignature(options["time"]) # Common time + else: + m_item = meter.TimeSignature("c") # Common time - note_stream.insert(0, m_item) - for item in parsed: - if isinstance(item, Pitch): - m_item = note.Note(item.note) - m_item.duration.quarterLength = item.duration * 4 - elif isinstance(item, Rest): - m_item = note.Rest(item.duration * 4) - elif isinstance(item, Chord): - m_item = chord.Chord(item.notes) - m_item.duration.quarterLength = item.duration * 4 - note_stream.append(m_item) - self.stream = note_stream.makeMeasures() + note_stream.insert(0, m_item) + for item in parsed: + if isinstance(item, Pitch): + m_item = note.Note(item.note) + m_item.duration.quarterLength = item.duration * 4 + elif isinstance(item, Rest): + m_item = note.Rest(item.duration * 4) + elif isinstance(item, Chord): + m_item = chord.Chord(item.notes) + m_item.duration.quarterLength = item.duration * 4 + note_stream.append(m_item) + # TODO: Is this ok? + self.stream = note_stream.makeMeasures() \ No newline at end of file