From bd4964d3c4776dbcf3cec9d4f28b88296d12f56f Mon Sep 17 00:00:00 2001 From: Benjamin Johnson <42893476+bmjcode@users.noreply.github.com> Date: Mon, 25 Aug 2025 19:51:15 -0400 Subject: [PATCH] Add more robust logic to find the last Bar in a ScorePart This avoids an AttributeError if the last object in a ScorePart's barlist is not a Bar. For example, \addlyrics blocks are represented by simple Python lists rather than Bar objects. Fixes #69. --- ly/musicxml/xml_objs.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ly/musicxml/xml_objs.py b/ly/musicxml/xml_objs.py index 098757b9..0e0ae412 100644 --- a/ly/musicxml/xml_objs.py +++ b/ly/musicxml/xml_objs.py @@ -96,8 +96,8 @@ def iterate_partgroup(self, group): def iterate_part(self, part): """The part is iterated.""" - if part.barlist: - last_bar = part.barlist[-1] + last_bar = part.last_bar() + if last_bar: last_bar_objs = last_bar.obj_list part.set_first_bar(self.divisions) self.musxml.create_part(part.name, part.abbr, part.midi) @@ -458,6 +458,12 @@ def extract_global_to_section(self, name): section.barlist.append(section_bar) return section + def last_bar(self): + """Returns the last Bar object in the score, or None if the score is empty.""" + for obj in reversed(self.barlist): + if isinstance(obj, Bar): + return obj + class Bar(): """ Representing the bar/measure.