code: def make_limit_node(root, limit):
      limit_node = etree.SubElement(root, 'limit',
                                    {'class': limit._limit_full_name})
      for attr in sorted(limit.attrs):
          desc = limit.attrs[attr]
          attr_type = desc.get('type', str)
          value = getattr(limit, attr)
          if 'default' in desc:
              default = (desc['default']() if callable(desc['default']) else
                         desc['default'])
              if value == default:
                  continue
          attr_node = etree.SubElement(limit_node, 'attr', name=attr)
          if attr_type == list:
              for val in value:
                  val_node = etree.SubElement(attr_node, 'value')
                  val_node.text = str(val)
          elif attr_type == dict:
              for key, val in sorted(value.items(), key=lambda x: x[0]):
                  val_node = etree.SubElement(attr_node, 'value', key=key)
                  val_node.text = str(val)
          else:
              attr_node.text = str(value)