code: def make_limit_node(root, limit):
      
  
      # Build the base limit node
      limit_node = etree.SubElement(root, 'limit',
                                    {'class': limit._limit_full_name})
  
      # Walk through all the recognized attributes
      for attr in sorted(limit.attrs):
          desc = limit.attrs[attr]
          attr_type = desc.get('type', str)
          value = getattr(limit, attr)
  
          # Determine the default value, if we have one...
          if 'default' in desc:
              default = (desc['default']() if callable(desc['default']) else
                         desc['default'])
  
              # Skip attributes that have their default settings
              if value == default:
                  continue
  
          # Set up the attr node
          attr_node = etree.SubElement(limit_node, 'attr', name=attr)
  
          # Treat lists and dicts specially
          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)
docs: Given a Limit object, generate an XML node.
  
      :param root: The root node of the XML tree being built.
      :param limit: The Limit object to serialize to XML.