Salome HOME
style: black format
[tools/sat.git] / src / ElementTreePython3.py
index 68635ce6d819df15a5a0f14af2f1164947dbab72..36dc08664bae7babfd957a192c593b1c7d90f6be 100644 (file)
@@ -33,7 +33,7 @@
 
 """
 
-#---------------------------------------------------------------------
+# ---------------------------------------------------------------------
 # Licensed to PSF under a Contributor Agreement.
 # See http://www.python.org/psf/license for licensing details.
 #
@@ -74,20 +74,27 @@ __all__ = [
     # public symbols
     "Comment",
     "dump",
-    "Element", "ElementTree",
-    "fromstring", "fromstringlist",
-    "iselement", "iterparse",
-    "parse", "ParseError",
-    "PI", "ProcessingInstruction",
+    "Element",
+    "ElementTree",
+    "fromstring",
+    "fromstringlist",
+    "iselement",
+    "iterparse",
+    "parse",
+    "ParseError",
+    "PI",
+    "ProcessingInstruction",
     "QName",
     "SubElement",
-    "tostring", "tostringlist",
+    "tostring",
+    "tostringlist",
     "TreeBuilder",
     "VERSION",
-    "XML", "XMLID",
+    "XML",
+    "XMLID",
     "XMLParser",
     "register_namespace",
-    ]
+]
 
 VERSION = "1.3.0"
 
@@ -109,14 +116,16 @@ class ParseError(SyntaxError):
         'position' - the line and column of the error
 
     """
+
     pass
 
+
 # --------------------------------------------------------------------
 
 
 def iselement(element):
     """Return True if *element* appears to be an Element."""
-    return hasattr(element, 'tag')
+    return hasattr(element, "tag")
 
 
 class Element:
@@ -165,8 +174,9 @@ class Element:
 
     def __init__(self, tag, attrib={}, **extra):
         if not isinstance(attrib, dict):
-            raise TypeError("attrib must be dict, not %s" % (
-                attrib.__class__.__name__,))
+            raise TypeError(
+                "attrib must be dict, not %s" % (attrib.__class__.__name__,)
+            )
         attrib = attrib.copy()
         attrib.update(extra)
         self.tag = tag
@@ -207,9 +217,10 @@ class Element:
         warnings.warn(
             "The behavior of this method will change in future versions.  "
             "Use specific 'len(elem)' or 'elem is not None' test instead.",
-            FutureWarning, stacklevel=2
-            )
-        return len(self._children) != 0 # emulate old behaviour, for now
+            FutureWarning,
+            stacklevel=2,
+        )
+        return len(self._children) != 0  # emulate old behaviour, for now
 
     def __getitem__(self, index):
         return self._children[index]
@@ -255,7 +266,7 @@ class Element:
         # Need to refer to the actual Python implementation, not the
         # shadowing C implementation.
         if not isinstance(e, _Element_Py):
-            raise TypeError('expected an Element, not %s' % type(e).__name__)
+            raise TypeError("expected an Element, not %s" % type(e).__name__)
 
     def remove(self, subelement):
         """Remove matching subelement.
@@ -281,8 +292,9 @@ class Element:
         warnings.warn(
             "This method will be removed in future versions.  "
             "Use 'list(elem)' or iteration over elem instead.",
-            DeprecationWarning, stacklevel=2
-            )
+            DeprecationWarning,
+            stacklevel=2,
+        )
         return self._children
 
     def find(self, path, namespaces=None):
@@ -414,7 +426,8 @@ class Element:
         warnings.warn(
             "This method will be removed in future versions.  "
             "Use 'elem.iter()' or 'list(elem.iter())' instead.",
-            PendingDeprecationWarning, stacklevel=2
+            PendingDeprecationWarning,
+            stacklevel=2,
         )
         return list(self.iter(tag))
 
@@ -485,6 +498,7 @@ def ProcessingInstruction(target, text=None):
         element.text = element.text + " " + text
     return element
 
+
 PI = ProcessingInstruction
 
 
@@ -502,41 +516,52 @@ class QName:
     be interpreted as a local name.
 
     """
+
     def __init__(self, text_or_uri, tag=None):
         if tag:
             text_or_uri = "{%s}%s" % (text_or_uri, tag)
         self.text = text_or_uri
+
     def __str__(self):
         return self.text
+
     def __repr__(self):
-        return '<QName %r>' % (self.text,)
+        return "<QName %r>" % (self.text,)
+
     def __hash__(self):
         return hash(self.text)
+
     def __le__(self, other):
         if isinstance(other, QName):
             return self.text <= other.text
         return self.text <= other
+
     def __lt__(self, other):
         if isinstance(other, QName):
             return self.text < other.text
         return self.text < other
+
     def __ge__(self, other):
         if isinstance(other, QName):
             return self.text >= other.text
         return self.text >= other
+
     def __gt__(self, other):
         if isinstance(other, QName):
             return self.text > other.text
         return self.text > other
+
     def __eq__(self, other):
         if isinstance(other, QName):
             return self.text == other.text
         return self.text == other
+
     def __ne__(self, other):
         if isinstance(other, QName):
             return self.text != other.text
         return self.text != other
 
+
 # --------------------------------------------------------------------
 
 
@@ -551,9 +576,10 @@ class ElementTree:
     contents will be used to initialize the tree with.
 
     """
+
     def __init__(self, element=None, file=None):
         # assert element is None or iselement(element)
-        self._root = element # first node
+        self._root = element  # first node
         if file:
             self.parse(file)
 
@@ -590,7 +616,7 @@ class ElementTree:
             if parser is None:
                 # If no parser was specified, create a default XMLParser
                 parser = XMLParser()
-                if hasattr(parser, '_parse_whole'):
+                if hasattr(parser, "_parse_whole"):
                     # The default XMLParser, when it comes from an accelerator,
                     # can define an internal _parse_whole API for efficiency.
                     # It can be used to parse the whole source without feeding
@@ -626,7 +652,8 @@ class ElementTree:
         warnings.warn(
             "This method will be removed in future versions.  "
             "Use 'tree.iter()' or 'list(tree.iter())' instead.",
-            PendingDeprecationWarning, stacklevel=2
+            PendingDeprecationWarning,
+            stacklevel=2,
         )
         return list(self.iter(tag))
 
@@ -648,8 +675,9 @@ class ElementTree:
                 "This search is broken in 1.3 and earlier, and will be "
                 "fixed in a future version.  If you rely on the current "
                 "behaviour, change it to %r" % path,
-                FutureWarning, stacklevel=2
-                )
+                FutureWarning,
+                stacklevel=2,
+            )
         return self._root.find(path, namespaces)
 
     def findtext(self, path, default=None, namespaces=None):
@@ -670,8 +698,9 @@ class ElementTree:
                 "This search is broken in 1.3 and earlier, and will be "
                 "fixed in a future version.  If you rely on the current "
                 "behaviour, change it to %r" % path,
-                FutureWarning, stacklevel=2
-                )
+                FutureWarning,
+                stacklevel=2,
+            )
         return self._root.findtext(path, default, namespaces)
 
     def findall(self, path, namespaces=None):
@@ -692,8 +721,9 @@ class ElementTree:
                 "This search is broken in 1.3 and earlier, and will be "
                 "fixed in a future version.  If you rely on the current "
                 "behaviour, change it to %r" % path,
-                FutureWarning, stacklevel=2
-                )
+                FutureWarning,
+                stacklevel=2,
+            )
         return self._root.findall(path, namespaces)
 
     def iterfind(self, path, namespaces=None):
@@ -714,16 +744,21 @@ class ElementTree:
                 "This search is broken in 1.3 and earlier, and will be "
                 "fixed in a future version.  If you rely on the current "
                 "behaviour, change it to %r" % path,
-                FutureWarning, stacklevel=2
-                )
+                FutureWarning,
+                stacklevel=2,
+            )
         return self._root.iterfind(path, namespaces)
 
-    def write(self, file_or_filename,
-              encoding=None,
-              xml_declaration=None,
-              default_namespace=None,
-              method=None, *,
-              short_empty_elements=True):
+    def write(
+        self,
+        file_or_filename,
+        encoding=None,
+        xml_declaration=None,
+        default_namespace=None,
+        method=None,
+        *,
+        short_empty_elements=True
+    ):
         """Write element tree to a file as XML.
 
         Arguments:
@@ -758,31 +793,42 @@ class ElementTree:
                 encoding = "us-ascii"
         enc_lower = encoding.lower()
         with _get_writer(file_or_filename, enc_lower) as write:
-            if method == "xml" and (xml_declaration or
-                    (xml_declaration is None and
-                     enc_lower not in ("utf-8", "us-ascii", "unicode"))):
+            if method == "xml" and (
+                xml_declaration
+                or (
+                    xml_declaration is None
+                    and enc_lower not in ("utf-8", "us-ascii", "unicode")
+                )
+            ):
                 declared_encoding = encoding
                 if enc_lower == "unicode":
                     # Retrieve the default encoding for the xml declaration
                     import locale
+
                     declared_encoding = locale.getpreferredencoding()
-                write("<?xml version='1.0' encoding='%s'?>\n" % (
-                    declared_encoding,))
+                write("<?xml version='1.0' encoding='%s'?>\n" % (declared_encoding,))
             if method == "text":
                 _serialize_text(write, self._root)
             else:
                 qnames, namespaces = _namespaces(self._root, default_namespace)
                 serialize = _serialize[method]
-                serialize(write, self._root, qnames, namespaces,
-                          short_empty_elements=short_empty_elements)
+                serialize(
+                    write,
+                    self._root,
+                    qnames,
+                    namespaces,
+                    short_empty_elements=short_empty_elements,
+                )
 
     def write_c14n(self, file):
         # lxml.etree compatibility.  use output method instead
         return self.write(file, method="c14n")
 
+
 # --------------------------------------------------------------------
 # serialization support
 
+
 @contextlib.contextmanager
 def _get_writer(file_or_filename, encoding):
     # returns text write method and release all resources after using
@@ -793,8 +839,9 @@ def _get_writer(file_or_filename, encoding):
         if encoding == "unicode":
             file = open(file_or_filename, "w")
         else:
-            file = open(file_or_filename, "w", encoding=encoding,
-                        errors="xmlcharrefreplace")
+            file = open(
+                file_or_filename, "w", encoding=encoding, errors="xmlcharrefreplace"
+            )
         with file:
             yield file.write
     else:
@@ -826,15 +873,15 @@ def _get_writer(file_or_filename, encoding):
                         file.tell = file_or_filename.tell
                     except AttributeError:
                         pass
-                file = io.TextIOWrapper(file,
-                                        encoding=encoding,
-                                        errors="xmlcharrefreplace",
-                                        newline="\n")
+                file = io.TextIOWrapper(
+                    file, encoding=encoding, errors="xmlcharrefreplace", newline="\n"
+                )
                 # Keep the original file open when the TextIOWrapper is
                 # destroyed
                 stack.callback(file.detach)
                 yield file.write
 
+
 def _namespaces(elem, default_namespace=None):
     # identify namespaces used in this tree
 
@@ -861,14 +908,14 @@ def _namespaces(elem, default_namespace=None):
                 if prefix:
                     qnames[qname] = "%s:%s" % (prefix, tag)
                 else:
-                    qnames[qname] = tag # default element
+                    qnames[qname] = tag  # default element
             else:
                 if default_namespace:
                     # FIXME: can this be handled in XML 1.0?
                     raise ValueError(
                         "cannot use non-qualified names with "
                         "default_namespace option"
-                        )
+                    )
                 qnames[qname] = qname
         except TypeError:
             _raise_serialization_error(qname)
@@ -896,8 +943,8 @@ def _namespaces(elem, default_namespace=None):
             add_qname(text.text)
     return qnames, namespaces
 
-def _serialize_xml(write, elem, qnames, namespaces,
-                   short_empty_elements, **kwargs):
+
+def _serialize_xml(write, elem, qnames, namespaces, short_empty_elements, **kwargs):
     tag = elem.tag
     text = elem.text
     if tag is Comment:
@@ -910,21 +957,20 @@ def _serialize_xml(write, elem, qnames, namespaces,
             if text:
                 write(_escape_cdata(text))
             for e in elem:
-                _serialize_xml(write, e, qnames, None,
-                               short_empty_elements=short_empty_elements)
+                _serialize_xml(
+                    write, e, qnames, None, short_empty_elements=short_empty_elements
+                )
         else:
             write("<" + tag)
             items = list(elem.items())
             if items or namespaces:
                 if namespaces:
-                    for v, k in sorted(namespaces.items(),
-                                       key=lambda x: x[1]):  # sort on prefix
+                    for v, k in sorted(
+                        namespaces.items(), key=lambda x: x[1]
+                    ):  # sort on prefix
                         if k:
                             k = ":" + k
-                        write(" xmlns%s=\"%s\"" % (
-                            k,
-                            _escape_attrib(v)
-                            ))
+                        write(' xmlns%s="%s"' % (k, _escape_attrib(v)))
                 for k, v in sorted(items):  # lexical order
                     if isinstance(k, QName):
                         k = k.text
@@ -932,85 +978,116 @@ def _serialize_xml(write, elem, qnames, namespaces,
                         v = qnames[v.text]
                     else:
                         v = _escape_attrib(v)
-                    write(" %s=\"%s\"" % (qnames[k], v))
+                    write(' %s="%s"' % (qnames[k], v))
             if text or len(elem) or not short_empty_elements:
                 write(">")
                 if text:
                     write(_escape_cdata(text))
                 for e in elem:
-                    _serialize_xml(write, e, qnames, None,
-                                   short_empty_elements=short_empty_elements)
+                    _serialize_xml(
+                        write,
+                        e,
+                        qnames,
+                        None,
+                        short_empty_elements=short_empty_elements,
+                    )
                 write("</" + tag + ">")
             else:
                 write(" />")
     if elem.tail:
         write(_escape_cdata(elem.tail))
 
+
 # add from cvw jan 2019
-def _serialize_pretty_xml(write, elem, qnames, namespaces,
-                     short_empty_elements, indent=0):
+def _serialize_pretty_xml(
+    write, elem, qnames, namespaces, short_empty_elements, indent=0
+):
     # print("*****pretty***** indent", elem.tag, indent)
     tag = elem.tag
     text = elem.text
     if tag is Comment:
-      write("<!--%s-->" % text)
+        write("<!--%s-->" % text)
     elif tag is ProcessingInstruction:
-      write("<?%s?>" % text)
+        write("<?%s?>" % text)
     else:
-      tag = qnames[tag]
-      if tag is None:
-        if text:
-          write(_escape_cdata(text))
-        for e in elem:
-          _serialize_pretty_xml(write, e, qnames, None,
-                         short_empty_elements=short_empty_elements, indent=indent)
-      else:
-        write(" "*indent + "<" + tag)
-        items = list(elem.items())
-        if items or namespaces:
-          if namespaces:
-            for v, k in sorted(namespaces.items(),
-                               key=lambda x: x[1]):  # sort on prefix
-              if k:
-                k = ":" + k
-              write(" xmlns%s=\"%s\"" % (
-                k,
-                _escape_attrib(v)
-              ))
-          for k, v in sorted(items):  # lexical order
-            # print("atrrib ", k, v)
-            if isinstance(k, QName):
-              k = k.text
-            if isinstance(v, QName):
-              v = qnames[v.text]
-            else:
-              v = _escape_attrib(v)
-            write(" %s=\"%s\"" % (qnames[k], v))
-        if text or len(elem) or not short_empty_elements:
-          if text:
-            write(">")
-            write(_escape_cdata(text))
-          else:
-            write(">\n")
-
-          for e in elem:
-            _serialize_pretty_xml(write, e, qnames, None,
-                           short_empty_elements=short_empty_elements, indent=indent+2)
-          write(" "*indent + "</" + tag + ">\n")
+        tag = qnames[tag]
+        if tag is None:
+            if text:
+                write(_escape_cdata(text))
+            for e in elem:
+                _serialize_pretty_xml(
+                    write,
+                    e,
+                    qnames,
+                    None,
+                    short_empty_elements=short_empty_elements,
+                    indent=indent,
+                )
         else:
-          write(" />\n")
+            write(" " * indent + "<" + tag)
+            items = list(elem.items())
+            if items or namespaces:
+                if namespaces:
+                    for v, k in sorted(
+                        namespaces.items(), key=lambda x: x[1]
+                    ):  # sort on prefix
+                        if k:
+                            k = ":" + k
+                        write(' xmlns%s="%s"' % (k, _escape_attrib(v)))
+                for k, v in sorted(items):  # lexical order
+                    # print("atrrib ", k, v)
+                    if isinstance(k, QName):
+                        k = k.text
+                    if isinstance(v, QName):
+                        v = qnames[v.text]
+                    else:
+                        v = _escape_attrib(v)
+                    write(' %s="%s"' % (qnames[k], v))
+            if text or len(elem) or not short_empty_elements:
+                if text:
+                    write(">")
+                    write(_escape_cdata(text))
+                else:
+                    write(">\n")
+
+                for e in elem:
+                    _serialize_pretty_xml(
+                        write,
+                        e,
+                        qnames,
+                        None,
+                        short_empty_elements=short_empty_elements,
+                        indent=indent + 2,
+                    )
+                write(" " * indent + "</" + tag + ">\n")
+            else:
+                write(" />\n")
     if elem.tail:
-      write(_escape_cdata(elem.tail))
+        write(_escape_cdata(elem.tail))
 
 
-HTML_EMPTY = ("area", "base", "basefont", "br", "col", "frame", "hr",
-              "img", "input", "isindex", "link", "meta", "param")
+HTML_EMPTY = (
+    "area",
+    "base",
+    "basefont",
+    "br",
+    "col",
+    "frame",
+    "hr",
+    "img",
+    "input",
+    "isindex",
+    "link",
+    "meta",
+    "param",
+)
 
 try:
     HTML_EMPTY = set(HTML_EMPTY)
 except NameError:
     pass
 
+
 def _serialize_html(write, elem, qnames, namespaces, **kwargs):
     tag = elem.tag
     text = elem.text
@@ -1030,14 +1107,12 @@ def _serialize_html(write, elem, qnames, namespaces, **kwargs):
             items = list(elem.items())
             if items or namespaces:
                 if namespaces:
-                    for v, k in sorted(namespaces.items(),
-                                       key=lambda x: x[1]):  # sort on prefix
+                    for v, k in sorted(
+                        namespaces.items(), key=lambda x: x[1]
+                    ):  # sort on prefix
                         if k:
                             k = ":" + k
-                        write(" xmlns%s=\"%s\"" % (
-                            k,
-                            _escape_attrib(v)
-                            ))
+                        write(' xmlns%s="%s"' % (k, _escape_attrib(v)))
                 for k, v in sorted(items):  # lexical order
                     if isinstance(k, QName):
                         k = k.text
@@ -1046,7 +1121,7 @@ def _serialize_html(write, elem, qnames, namespaces, **kwargs):
                     else:
                         v = _escape_attrib_html(v)
                     # FIXME: handle boolean attributes
-                    write(" %s=\"%s\"" % (qnames[k], v))
+                    write(' %s="%s"' % (qnames[k], v))
             write(">")
             ltag = tag.lower()
             if text:
@@ -1061,19 +1136,21 @@ def _serialize_html(write, elem, qnames, namespaces, **kwargs):
     if elem.tail:
         write(_escape_cdata(elem.tail))
 
+
 def _serialize_text(write, elem):
     for part in elem.itertext():
         write(part)
     if elem.tail:
         write(elem.tail)
 
+
 _serialize = {
     "xml": _serialize_xml,
     "pretty_xml": _serialize_pretty_xml,
     "html": _serialize_html,
     "text": _serialize_text,
-# this optional method is imported at the end of the module
-#   "c14n": _serialize_c14n,
+    # this optional method is imported at the end of the module
+    #   "c14n": _serialize_c14n,
 }
 
 
@@ -1096,6 +1173,7 @@ def register_namespace(prefix, uri):
             del _namespace_map[k]
     _namespace_map[uri] = prefix
 
+
 _namespace_map = {
     # "well-known" namespace prefixes
     "http://www.w3.org/XML/1998/namespace": "xml",
@@ -1111,10 +1189,10 @@ _namespace_map = {
 # For tests and troubleshooting
 register_namespace._namespace_map = _namespace_map
 
+
 def _raise_serialization_error(text):
-    raise TypeError(
-        "cannot serialize %r (type %s)" % (text, type(text).__name__)
-        )
+    raise TypeError("cannot serialize %r (type %s)" % (text, type(text).__name__))
+
 
 def _escape_cdata(text):
     # escape character data
@@ -1132,6 +1210,7 @@ def _escape_cdata(text):
     except (TypeError, AttributeError):
         _raise_serialization_error(text)
 
+
 def _escape_attrib(text):
     # escape attribute value
     try:
@@ -1141,14 +1220,15 @@ def _escape_attrib(text):
             text = text.replace("<", "&lt;")
         if ">" in text:
             text = text.replace(">", "&gt;")
-        if "\"" in text:
-            text = text.replace("\"", "&quot;")
+        if '"' in text:
+            text = text.replace('"', "&quot;")
         if "\n" in text:
             text = text.replace("\n", "&#10;")
         return text
     except (TypeError, AttributeError):
         _raise_serialization_error(text)
 
+
 def _escape_attrib_html(text):
     # escape attribute value
     try:
@@ -1156,16 +1236,17 @@ def _escape_attrib_html(text):
             text = text.replace("&", "&amp;")
         if ">" in text:
             text = text.replace(">", "&gt;")
-        if "\"" in text:
-            text = text.replace("\"", "&quot;")
+        if '"' in text:
+            text = text.replace('"', "&quot;")
         return text
     except (TypeError, AttributeError):
         _raise_serialization_error(text)
 
+
 # --------------------------------------------------------------------
 
-def tostring(element, encoding=None, method=None, *,
-             short_empty_elements=True):
+
+def tostring(element, encoding=None, method=None, *, short_empty_elements=True):
     """Generate string representation of XML element.
 
     All subelements are included.  If encoding is "unicode", a string
@@ -1178,13 +1259,16 @@ def tostring(element, encoding=None, method=None, *,
     Returns an (optionally) encoded string containing the XML data.
 
     """
-    stream = io.StringIO() if encoding == 'unicode' else io.BytesIO()
-    ElementTree(element).write(stream, encoding, method=method,
-                               short_empty_elements=short_empty_elements)
+    stream = io.StringIO() if encoding == "unicode" else io.BytesIO()
+    ElementTree(element).write(
+        stream, encoding, method=method, short_empty_elements=short_empty_elements
+    )
     return stream.getvalue()
 
+
 class _ListDataStream(io.BufferedIOBase):
     """An auxiliary stream accumulating into a list reference."""
+
     def __init__(self, lst):
         self.lst = lst
 
@@ -1200,12 +1284,13 @@ class _ListDataStream(io.BufferedIOBase):
     def tell(self):
         return len(self.lst)
 
-def tostringlist(element, encoding=None, method=None, *,
-                 short_empty_elements=True):
+
+def tostringlist(element, encoding=None, method=None, *, short_empty_elements=True):
     lst = []
     stream = _ListDataStream(lst)
-    ElementTree(element).write(stream, encoding, method=method,
-                               short_empty_elements=short_empty_elements)
+    ElementTree(element).write(
+        stream, encoding, method=method, short_empty_elements=short_empty_elements
+    )
     return lst
 
 
@@ -1227,6 +1312,7 @@ def dump(elem):
     if not tail or tail[-1] != "\n":
         sys.stdout.write("\n")
 
+
 # --------------------------------------------------------------------
 # parsing
 
@@ -1273,7 +1359,6 @@ def iterparse(source, events=None, parser=None):
 
 
 class XMLPullParser:
-
     def __init__(self, events=None, *, _parser=None):
         # The _parser argument is for internal use only and must not be relied
         # upon in user code. It will be removed in a future release.
@@ -1342,7 +1427,6 @@ class XMLPullParser:
 
 
 class _IterParseIterator:
-
     def __init__(self, source, events, parser, close_source=False):
         # Use the internal, undocumented _parser argument for now; When the
         # parser argument of iterparse is removed, this can be killed.
@@ -1415,9 +1499,11 @@ def XMLID(text, parser=None):
             ids[id] = elem
     return tree, ids
 
+
 # Parse XML document from string constant.  Alias for XML().
 fromstring = XML
 
+
 def fromstringlist(sequence, parser=None):
     """Parse XML document from sequence of string fragments.
 
@@ -1433,6 +1519,7 @@ def fromstringlist(sequence, parser=None):
         parser.feed(text)
     return parser.close()
 
+
 # --------------------------------------------------------------------
 
 
@@ -1449,11 +1536,12 @@ class TreeBuilder:
     to create new Element instances, as necessary.
 
     """
+
     def __init__(self, element_factory=None):
-        self._data = [] # data collector
-        self._elem = [] # element stack
-        self._last = None # last element
-        self._tail = None # true if we're after an end tag
+        self._data = []  # data collector
+        self._elem = []  # element stack
+        self._last = None  # last element
+        self._tail = None  # true if we're after an end tag
         if element_factory is None:
             element_factory = Element
         self._factory = element_factory
@@ -1503,9 +1591,10 @@ class TreeBuilder:
         """
         self._flush()
         self._last = self._elem.pop()
-        assert self._last.tag == tag,\
-               "end tag mismatch (expected %s, got %s)" % (
-                   self._last.tag, tag)
+        assert self._last.tag == tag, "end tag mismatch (expected %s, got %s)" % (
+            self._last.tag,
+            tag,
+        )
         self._tail = 1
         return self._last
 
@@ -1531,7 +1620,7 @@ class XMLParser:
             except ImportError:
                 raise ImportError(
                     "No module named expat; use SimpleXMLTreeBuilder instead"
-                    )
+                )
         parser = expat.ParserCreate(encoding, "}")
         if target is None:
             target = TreeBuilder()
@@ -1539,19 +1628,19 @@ class XMLParser:
         self.parser = self._parser = parser
         self.target = self._target = target
         self._error = expat.error
-        self._names = {} # name memo cache
+        self._names = {}  # name memo cache
         # main callbacks
         parser.DefaultHandlerExpand = self._default
-        if hasattr(target, 'start'):
+        if hasattr(target, "start"):
             parser.StartElementHandler = self._start
-        if hasattr(target, 'end'):
+        if hasattr(target, "end"):
             parser.EndElementHandler = self._end
-        if hasattr(target, 'data'):
+        if hasattr(target, "data"):
             parser.CharacterDataHandler = target.data
         # miscellaneous callbacks
-        if hasattr(target, 'comment'):
+        if hasattr(target, "comment"):
             parser.CommentHandler = target.comment
-        if hasattr(target, 'pi'):
+        if hasattr(target, "pi"):
             parser.ProcessingInstructionHandler = target.pi
         # Configure pyexpat: buffering, new-style attribute handling.
         parser.buffer_text = 1
@@ -1562,7 +1651,7 @@ class XMLParser:
         try:
             self.version = "Expat %d.%d.%d" % expat.version_info
         except AttributeError:
-            pass # unknown
+            pass  # unknown
 
     def _setevents(self, events_queue, events_to_report):
         # Internal API for XMLPullParser
@@ -1577,22 +1666,30 @@ class XMLParser:
             if event_name == "start":
                 parser.ordered_attributes = 1
                 parser.specified_attributes = 1
-                def handler(tag, attrib_in, event=event_name, append=append,
-                            start=self._start):
+
+                def handler(
+                    tag, attrib_in, event=event_name, append=append, start=self._start
+                ):
                     append((event, start(tag, attrib_in)))
+
                 parser.StartElementHandler = handler
             elif event_name == "end":
-                def handler(tag, event=event_name, append=append,
-                            end=self._end):
+
+                def handler(tag, event=event_name, append=append, end=self._end):
                     append((event, end(tag)))
+
                 parser.EndElementHandler = handler
             elif event_name == "start-ns":
+
                 def handler(prefix, uri, event=event_name, append=append):
                     append((event, (prefix or "", uri or "")))
+
                 parser.StartNamespaceDeclHandler = handler
             elif event_name == "end-ns":
+
                 def handler(prefix, event=event_name, append=append):
                     append((event, None))
+
                 parser.EndNamespaceDeclHandler = handler
             else:
                 raise ValueError("unknown event %r" % event_name)
@@ -1623,7 +1720,7 @@ class XMLParser:
         attrib = {}
         if attr_list:
             for i in range(0, len(attr_list), 2):
-                attrib[fixname(attr_list[i])] = attr_list[i+1]
+                attrib[fixname(attr_list[i])] = attr_list[i + 1]
         return self.target.start(tag, attrib)
 
     def _end(self, tag):
@@ -1641,17 +1738,17 @@ class XMLParser:
                 data_handler(self.entity[text[1:-1]])
             except KeyError:
                 from xml.parsers import expat
+
                 err = expat.error(
-                    "undefined entity %s: line %d, column %d" %
-                    (text, self.parser.ErrorLineNumber,
-                    self.parser.ErrorColumnNumber)
-                    )
-                err.code = 11 # XML_ERROR_UNDEFINED_ENTITY
+                    "undefined entity %s: line %d, column %d"
+                    % (text, self.parser.ErrorLineNumber, self.parser.ErrorColumnNumber)
+                )
+                err.code = 11  # XML_ERROR_UNDEFINED_ENTITY
                 err.lineno = self.parser.ErrorLineNumber
                 err.offset = self.parser.ErrorColumnNumber
                 raise err
         elif prefix == "<" and text[:9] == "<!DOCTYPE":
-            self._doctype = [] # inside a doctype declaration
+            self._doctype = []  # inside a doctype declaration
         elif self._doctype is not None:
             # parse doctype contents
             if prefix == ">":
@@ -1692,7 +1789,7 @@ class XMLParser:
             "This method of XMLParser is deprecated.  Define doctype() "
             "method on the TreeBuilder target.",
             DeprecationWarning,
-            )
+        )
 
     # sentinel, if doctype is redefined in a subclass
     __doctype = doctype
@@ -1707,7 +1804,7 @@ class XMLParser:
     def close(self):
         """Finish feeding data to parser and return element structure."""
         try:
-            self.parser.Parse("", 1) # end of data
+            self.parser.Parse("", 1)  # end of data
         except self._error as v:
             self._raiseerror(v)
         try:
@@ -1732,4 +1829,4 @@ try:
     # Element, SubElement, ParseError, TreeBuilder, XMLParser
     from _elementtree import *
 except ImportError:
-    pass
\ No newline at end of file
+    pass