def _build_attributes()

in moonlight/evaluation/musicxml.py [0:0]


  def _build_attributes(self, staff_num, orig_measure):
    """Builds a new <attributes> tag for the given measure.

    If the measure already contains an <attributes> tag, all children are copied
    as long as they do not have a <staff> tag that's incompatible with the given
    staff number.

    If the existing <attributes> don't contain a <divisions> tag, we take the
    most recent <divisions> from any measure on any part. The <divisions> tag is
    required at the start of the score.

    Args:
      staff_num: Index of the staff across all parts.
      orig_measure: The original <measure> tag, which may or may not contain its
        own <attributes>.

    Returns:
      A new <attributes> tag, keeping any applicable attributes from
      `orig_measure`, and the most recent <divisions>.
    """
    new_attributes = etree.Element('attributes')

    orig_attributes = orig_measure.find('attributes')
    if orig_attributes is not None:
      for attribute in orig_attributes:
        new_attribute = _filter_for_staff(staff_num, attribute)
        if new_attribute is not None:
          new_attributes.append(new_attribute)
    # Look for the most recent "divisions" tag.
    def find_divisions():
      divisions = None
      for part in orig_measure.getparent().getparent().findall('part'):
        for prev_measure in part.findall('measure'):
          prev_attrs = prev_measure.find('attributes')
          if (prev_attrs is not None and
              prev_attrs.find('divisions') is not None):
            divisions = prev_attrs.find('divisions')
          if prev_measure is orig_measure:
            # Done.
            if divisions is None:
              raise ValueError('<divisions> is required')
            # Copy the tag, or else when appending the tag to a new element, it
            # will be deleted from the old element.
            return copy.deepcopy(divisions)

    if new_attributes.find('divisions') is None:
      new_attributes.append(find_divisions())
    return new_attributes