def parse_limit_node(db, idx, limit):
<EOL>klass = utils.find_entrypoint('<STR_LIT>', limit.get('<STR_LIT:class>'),<EOL>required=True)<EOL>required = set(k for k, v in list(klass.attrs.items())<EOL>if '<STR_LIT:default>' not in v)<EOL>attrs = {}<EOL>for child in limit:<EOL><INDENT>if child.tag != '<STR_LIT>':<EOL><INDENT>warnings.warn("<STR_LIT>"<EOL>"<STR_LIT>" % (child.tag, idx))<EOL>continue<EOL><DEDENT>attr = child.get('<STR_LIT:name>')<EOL>if attr not in klass.attrs:<EOL><INDENT>warnings.warn("<STR_LIT>"<EOL>"<STR_LIT>" % (idx, attr))<EOL>continue<EOL><DEDENT>desc = klass.attrs[attr]<EOL>attr_type = desc.get('<STR_LIT:type>', str)<EOL>if attr_type == list:<EOL><INDENT>subtype = desc.get('<STR_LIT>', str)<EOL>value = []<EOL>try:<EOL><INDENT>for j, grandchild in enumerate(child):<EOL><INDENT>if grandchild.tag != '<STR_LIT:value>':<EOL><INDENT>warnings.warn("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>(grandchild.tag, attr, idx))<EOL>continue<EOL><DEDENT>value.append(subtype(grandchild.text))<EOL><DEDENT><DEDENT>except ValueError:<EOL><INDENT>warnings.warn("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>(grandchild.text, j, attr, idx))<EOL>continue<EOL><DEDENT><DEDENT>elif attr_type == dict:<EOL><INDENT>subtype = desc.get('<STR_LIT>', str)<EOL>value = {}<EOL>for grandchild in child:<EOL><INDENT>if grandchild.tag != '<STR_LIT:value>':<EOL><INDENT>warnings.warn("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>(grandchild.tag, attr, idx))<EOL>continue<EOL><DEDENT>elif '<STR_LIT:key>' not in grandchild.attrib:<EOL><INDENT>warnings.warn("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>(attr, idx))<EOL>continue<EOL><DEDENT>try:<EOL><INDENT>value[grandchild.get('<STR_LIT:key>')] = subtype(grandchild.text)<EOL><DEDENT>except ValueError:<EOL><INDENT>warnings.warn("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>(grandchild.text, grandchild.get('<STR_LIT:key>'),<EOL>attr, idx))<EOL>continue<EOL><DEDENT><DEDENT><DEDENT>elif attr_type == bool:<EOL><INDENT>try:<EOL><INDENT>value = config.Config.to_bool(child.text)<EOL><DEDENT>except ValueError:<EOL><INDENT>warnings.warn("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" % (child.text, attr, idx))<EOL>continue<EOL><DEDENT><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>value = attr_type(child.text)<EOL><DEDENT>except ValueError:<EOL><INDENT>warnings.warn("<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>(child.text, attr, idx))<EOL>continue<EOL><DEDENT><DEDENT>attrs[attr] = value<EOL>required.discard(attr)<EOL><DEDENT>if required:<EOL><INDENT>raise TypeError("<STR_LIT>" %<EOL>('<STR_LIT:U+002CU+0020>'.join(repr(a) for a in sorted(required))))<EOL><DEDENT>return klass(db, **attrs)<EOL>
Given an XML node describing a limit, return a Limit object.

:param db: Handle for the Redis database.
:param idx: The index of the limit in the XML file; used for error
            reporting.
:param limit: The XML node describing the limit.