diff options
Diffstat (limited to 'cli/lib/project/xml_parser.py')
-rw-r--r-- | cli/lib/project/xml_parser.py | 133 |
1 files changed, 70 insertions, 63 deletions
diff --git a/cli/lib/project/xml_parser.py b/cli/lib/project/xml_parser.py index 131d6c1..d467889 100644 --- a/cli/lib/project/xml_parser.py +++ b/cli/lib/project/xml_parser.py @@ -34,73 +34,80 @@ from project import common class ElementExtras(object): - @staticmethod - def get_attrib(node, key): - if key not in node.attrib: - raise common.MissingAttribute( - node.origin, '{} lacks a @{} attribute'.format(node.tag, key)) - val = node.attrib.get(key) - if len(val) == 0: - raise common.MissingAttribute( - node.origin, - '<{}>\'s @{} attribute is empty'.format(node.tag, key)) - return val - - @staticmethod - def limit_attribs(node, keys): - bad_keys = set(node.attrib) - set(keys) - if len(bad_keys): - raise common.UnknownAttributes( - node.origin, - '{} contains unsupported attributes: {} '.format(node.tag, bad_keys)) - - @staticmethod - def extend_element(): - ET.Element.get_attrib = ElementExtras.get_attrib - ET.Element.limit_attribs = ElementExtras.limit_attribs + @staticmethod + def get_attrib(node, key): + if key not in node.attrib: + raise common.MissingAttribute( + node.origin, '{} lacks a @{} attribute'.format(node.tag, key)) + val = node.attrib.get(key) + if len(val) == 0: + raise common.MissingAttribute( + node.origin, + '<{}>\'s @{} attribute is empty'.format(node.tag, key)) + return val + + @staticmethod + def limit_attribs(node, keys): + bad_keys = set(node.attrib) - set(keys) + if len(bad_keys): + raise common.UnknownAttributes( + node.origin, + '{} contains unsupported attributes: {} '.format(node.tag, + bad_keys)) + + @staticmethod + def extend_element(): + ET.Element.get_attrib = ElementExtras.get_attrib + ET.Element.limit_attribs = ElementExtras.limit_attribs class AnnotatedXMLTreeBuilder(XMLTreeBuilder): - def __init__(self): - super(AnnotatedXMLTreeBuilder, self).__init__() - self.file_name = None - - def _start_fixup(self, element): - """Adds element source annotation as the ElementTree is built.""" - # Grab the line/col from expat, but expect the path - # to be passed in. - element.origin = common.Origin(self.file_name, - self._parser.CurrentLineNumber, - self._parser.CurrentColumnNumber) - return element - - def _start(self, tag, attrib_in): - """Thunks the XMLTreeBuilder _start adding the element annotations.""" - # If _start_list was supported, then we'll see a list and should call over. - if type(attrib_in) == list: - return self._start_list(tag, attrib_in) - - element = super(AnnotatedXMLTreeBuilder, self)._start(tag, attrib_in) - return self._start_fixup(element) - - def _start_list(self, tag, attrib_in): - """Thunks the XMLTreeBuilder _start_list adding the element annotations.""" - element = super(AnnotatedXMLTreeBuilder, self)._start_list(tag, attrib_in) - return self._start_fixup(element) - - def subclass_fixups(self): - """Updates the parser callback to the _start element in this instance.""" - # This may clobber start_list, but we hide that in _start. - self._parser.StartElementHandler = self._start + def __init__(self): + super(AnnotatedXMLTreeBuilder, self).__init__() + self.file_name = None + + def _start_fixup(self, element): + """Adds element source annotation as the ElementTree is built.""" + # Grab the line/col from expat, but expect the path + # to be passed in. + element.origin = common.Origin(self.file_name, + self._parser.CurrentLineNumber, + self._parser.CurrentColumnNumber) + return element + + def _start(self, tag, attrib_in): + """Thunks the XMLTreeBuilder _start adding the element annotations.""" + # If _start_list was supported, then we'll see a list and should call + # over. + if type(attrib_in) == list: + return self._start_list(tag, attrib_in) + + element = super(AnnotatedXMLTreeBuilder, self)._start(tag, attrib_in) + return self._start_fixup(element) + + def _start_list(self, tag, attrib_in): + """Thunks the XMLTreeBuilder _start_list adding the element + annotations. + """ + element = super(AnnotatedXMLTreeBuilder, self)._start_list(tag, + attrib_in) + return self._start_fixup(element) + + def subclass_fixups(self): + """Updates the parser callback to the _start element in this + instance. + """ + # This may clobber start_list, but we hide that in _start. + self._parser.StartElementHandler = self._start def parse(path): - """Replaces ET.parse() as an entry point for adding source annotations.""" - ElementExtras.extend_element() - parser = AnnotatedXMLTreeBuilder() - parser.file_name = str(path) - if hasattr(path, 'name'): - parser.file_name = path.name - parser.subclass_fixups() - return ET.parse(path, parser=parser) + """Replaces ET.parse() as an entry point for adding source annotations.""" + ElementExtras.extend_element() + parser = AnnotatedXMLTreeBuilder() + parser.file_name = str(path) + if hasattr(path, 'name'): + parser.file_name = path.name + parser.subclass_fixups() + return ET.parse(path, parser=parser) |