old_contents: import lxml.etree as ET
  import argparse
  
  def get_pb_type_chain(node):
      pb_types = []
      while True:
          parent = node.getparent()
  
          if parent is None:
              return list(reversed(pb_types))
  
          if parent.tag == 'pb_type':
              pb_types.append(parent.attrib['name'])
  
          node = parent
  
  def specialized_chain_name(pat):
      return '.'.join(get_pb_type_chain(pat)[:2])
  
  def specialize_chain(pat):
      pat.attrib['name'] = '{}.{}'.format(
              specialized_chain_name(pat),
              pat.attrib['name'])
  
  def main():
      parser = argparse.ArgumentParser(description="Converts site local carry chains to fabric global.");
      parser.add_argument('--input_arch_xml', required=True, help="Input arch.xml to specialized.")
  
      args = parser.parse_args()
  
      arch_xml = ET.ElementTree()
      root_element = arch_xml.parse(args.input_arch_xml)
  
      tiles = {}
      for pat in root_element.iter('pack_pattern'):
          if 'CARRY' in pat.attrib['name']:
              pb_types = get_pb_type_chain(pat)
              if pb_types[0] not in tiles:
                  tiles[pb_types[0]] = []
  
              tiles[pb_types[0]].append(pat)
  
      # Specialize first chain in each tile, and delete the rest.
      for tile, pats in tiles.items():
          pat_indices, _ = zip(*sorted(enumerate((get_pb_type_chain(pat)[1] for pat in pats)), key=lambda x: x[1]))
          chain_to_keep = specialized_chain_name(pats[pat_indices[0]])
  
          for pat_idx in pat_indices:
              pat = pats[pat_idx]
  
              if specialized_chain_name(pat) == chain_to_keep:
                  specialize_chain(pat)
              else:
                  pat.getparent().remove(pat)
  
      print(ET.tostring(arch_xml, pretty_print=True).decode('utf-8'))
  
  if __name__ == '__main__':
      main()
  
new_contents: import lxml.etree as ET
  import argparse
  
  def get_pb_type_chain(node):
      pb_types = []
      while True:
          parent = node.getparent()
  
          if parent is None:
              return list(reversed(pb_types))
  
          if parent.tag == 'pb_type':
              pb_types.append(parent.attrib['name'])
  
          node = parent
  
  def specialized_chain_name(pat):
      return '.'.join(get_pb_type_chain(pat)[:2])
  
  def specialize_chain(pat):
      pat.attrib['name'] = '{}.{}'.format(
              specialized_chain_name(pat),
              pat.attrib['name'])
  
  def main():
      parser = argparse.ArgumentParser(description="Converts site local carry chains to fabric global.");
      parser.add_argument('--input_arch_xml', required=True, help="Input arch.xml to specialized.")
  
      args = parser.parse_args()
  
      arch_xml = ET.ElementTree()
      root_element = arch_xml.parse(args.input_arch_xml)
  
      tiles = {}
      for pat in root_element.iter('pack_pattern'):
          if 'CARRY' in pat.attrib['name']:
              pb_types = get_pb_type_chain(pat)
              if pb_types[0] not in tiles:
                  tiles[pb_types[0]] = []
  
              tiles[pb_types[0]].append(pat)
  
      # Specialize first chain in each tile, and delete the rest.
      for tile, pats in tiles.items():
          patterns = []
          for idx, pat in enumerate(pats):
              parts = get_pb_type_chain(pat)
              if len(parts) > 1:
                  patterns.append((idx, parts[1]))
              else:
                  patterns.append((idx, ''))
  
          pat_indices, _ = zip(*sorted(patterns, key=lambda x: x[1]))
          chain_to_keep = specialized_chain_name(pats[pat_indices[0]])
  
          for pat_idx in pat_indices:
              pat = pats[pat_idx]
  
              if specialized_chain_name(pat) == chain_to_keep:
                  specialize_chain(pat)
              else:
                  pat.getparent().remove(pat)
  
      print(ET.tostring(arch_xml, pretty_print=True).decode('utf-8'))
  
  if __name__ == '__main__':
      main()
  
subject: Handle testarch pattern definition.