frescobaldi / python-ly

A Python package and commandline tool to manipulate LilyPond files
https://pypi.org/project/python-ly
136 stars 35 forks source link

MusicXML export fails on "check_simultan self.sections.pop()" #76

Open ExecutorElassus opened 8 years ago

ExecutorElassus commented 8 years ago

I have the following file transkription kayser 6. messe d-moll - flattened.ly.zip

Export to MusicXML fails with the following error:

Traceback (most recent call last):
  File "/usr/lib64/python2.7/site-packages/frescobaldi_app/file_export/__init__.py", line 65, in exportMusicXML
    writer.parse_text(doc.toPlainText())
  File "/usr/lib64/python2.7/site-packages/ly/musicxml/lymus2musxml.py", line 102, in parse_text
    self.parse_document(doc)
  File "/usr/lib64/python2.7/site-packages/ly/musicxml/lymus2musxml.py", line 119, in parse_document
    self.parse_tree(mustree)
  File "/usr/lib64/python2.7/site-packages/ly/musicxml/lymus2musxml.py", line 133, in parse_tree
    self.parse_nodes(mus_nodes)
  File "/usr/lib64/python2.7/site-packages/ly/musicxml/lymus2musxml.py", line 145, in parse_nodes
    func_call(m)
  File "/usr/lib64/python2.7/site-packages/ly/musicxml/lymus2musxml.py", line 624, in End
    self.mediator.check_simultan()
  File "/usr/lib64/python2.7/site-packages/ly/musicxml/ly2xml_mediator.py", line 293, in check_simultan
    self.sections.pop()
IndexError: pop from empty list

(the \includes in that file are all layout/font options. The entire file tree can be found here).

What is going wrong here? Is there some issue of formatting that isn't being correctly interpreted?

Thanks for the help

uliska commented 8 years ago

Note that this file can only be compiled in the original context as otherwise the includes cannot be resolved.

I suspected this failed include could be the reason but when placing the flattened file in the original context a) it became compilable and b) the MusicXML export fails with the same message. So this is not the issue.

The other thing is that I tried that with python-ly from Git (where the OP obviously has the packaged version), and the error is the same. So that isn't a reason either.

mtarenskeen commented 5 years ago

I bumped into this bug when trying a very simple test:

  1. create a very simple minimal.ly test with for example only { c' d' e' f' }
  2. ly musicxml minimal.ly -o minimal.musicxml
  3. musicxml2ly minimal.musicxml -o minimal2.ly
  4. ly musicxml minimal2.ly -o minimal2.musicxml

Unknown command: \mergeDifferentlyDottedOn Unknown command: \mergeDifferentlyHeadedOn Warning: End not implemented! 'NoneType' object has no attribute 'merge_voice' Traceback (most recent call last): File "/usr/bin/ly", line 4, in sys.exit(main()) File "/usr/lib/python3.7/site-packages/ly/cli/main.py", line 288, in main c.run(options, cursor, output) File "/usr/lib/python3.7/site-packages/ly/cli/command.py", line 221, in run writer.parse_document(cursor.document, absolute) File "/usr/lib/python3.7/site-packages/ly/musicxml/lymus2musxml.py", line 119, in parse_document self.parse_tree(mustree) File "/usr/lib/python3.7/site-packages/ly/musicxml/lymus2musxml.py", line 133, in parse_tree self.parse_nodes(mus_nodes) File "/usr/lib/python3.7/site-packages/ly/musicxml/lymus2musxml.py", line 145, in parse_nodes func_call(m) File "/usr/lib/python3.7/site-packages/ly/musicxml/lymus2musxml.py", line 624, in End self.mediator.check_simultan() File "/usr/lib/python3.7/site-packages/ly/musicxml/ly2xml_mediator.py", line 293, in check_simultan self.sections.pop() IndexError: pop from empty list

mtarenskeen commented 5 years ago

As a workaround I changed line 293 in ly2xml_mediator.py. I am not enough of a Python programmer to judge if this makes any sense, but it worked for me now.

        # self.sections.pop()
        if self.sections:
            self.sections.pop()
shoorick commented 2 years ago

The same situation in 2022. As written in previous comment it's possible to patch /usr/lib/python3/dist-packages/ly/musicxml/ly2xml_mediator.py — different lines but the same code

301c301,302
<         self.sections.pop()
---
>         if self.sections:
>             self.sections.pop()