Create _attr/_attrNS lazily.
authorMartin v. Löwis <martin@v.loewis.de>
Sun, 19 Feb 2012 19:55:05 +0000 (20:55 +0100)
committerMartin v. Löwis <martin@v.loewis.de>
Sun, 19 Feb 2012 19:55:05 +0000 (20:55 +0100)
Lib/xml/dom/expatbuilder.py
Lib/xml/dom/minidom.py

index b4b28e4d553f3716ec66d3e8961d60c8d5a8a5bf..ff9c1f16904ffffc390a11e14db4c137dbd63cc2 100644 (file)
@@ -760,6 +760,7 @@ class Namespaces:
             del self._ns_ordered_prefixes[:]
 
         if attributes:
+            node._ensure_attributes()
             _attrs = node._attrs
             _attrsNS = node._attrsNS
             for i in range(0, len(attributes), 2):
index c7de12c89cd3be73f630134e0c2027e0814f1d8c..7e2f88e3609246fc70a2d02766b3367635e8554d 100644 (file)
@@ -689,13 +689,21 @@ class Element(Node):
         self.childNodes = NodeList()
         self.nextSibling = self.previousSibling = None
 
-        self._attrs = {}   # attributes are double-indexed:
-        self._attrsNS = {} #    tagName -> Attribute
-                           #    URI,localName -> Attribute
-                           # in the future: consider lazy generation
-                           # of attribute objects this is too tricky
-                           # for now because of headaches with
-                           # namespaces.
+        # Attribute dictionaries are lazily created
+        # attributes are double-indexed:
+        #    tagName -> Attribute
+        #    URI,localName -> Attribute
+        # in the future: consider lazy generation
+        # of attribute objects this is too tricky
+        # for now because of headaches with
+        # namespaces.
+        self._attrs = None
+        self._attrsNS = None
+
+    def _ensure_attributes(self):
+        if self._attrs is None:
+            self._attrs = {}
+            self._attrsNS = {}
 
     def _get_localName(self):
         try:
@@ -707,8 +715,9 @@ class Element(Node):
         return self.tagName
 
     def unlink(self):
-        for attr in list(self._attrs.values()):
-            attr.unlink()
+        if self._attrs is not None:
+            for attr in list(self._attrs.values()):
+                attr.unlink()
         self._attrs = None
         self._attrsNS = None
         Node.unlink(self)
@@ -755,14 +764,19 @@ class Element(Node):
                 attr.nodeName = qualifiedName
 
     def getAttributeNode(self, attrname):
+        if self._attrs is None:
+            return None
         return self._attrs.get(attrname)
 
     def getAttributeNodeNS(self, namespaceURI, localName):
+        if self._attrsNS is None:
+            return None
         return self._attrsNS.get((namespaceURI, localName))
 
     def setAttributeNode(self, attr):
         if attr.ownerElement not in (None, self):
             raise xml.dom.InuseAttributeErr("attribute node already owned")
+        self._ensure_attributes()
         old1 = self._attrs.get(attr.name, None)
         if old1 is not None:
             self.removeAttributeNode(old1)
@@ -781,6 +795,8 @@ class Element(Node):
     setAttributeNodeNS = setAttributeNode
 
     def removeAttribute(self, name):
+        if self._attrsNS is None:
+            raise xml.dom.NotFoundErr()
         try:
             attr = self._attrs[name]
         except KeyError:
@@ -788,6 +804,8 @@ class Element(Node):
         self.removeAttributeNode(attr)
 
     def removeAttributeNS(self, namespaceURI, localName):
+        if self._attrsNS is None:
+            raise xml.dom.NotFoundErr()
         try:
             attr = self._attrsNS[(namespaceURI, localName)]
         except KeyError:
@@ -810,9 +828,13 @@ class Element(Node):
     removeAttributeNodeNS = removeAttributeNode
 
     def hasAttribute(self, name):
+        if self._attrs is None:
+            return False
         return name in self._attrs
 
     def hasAttributeNS(self, namespaceURI, localName):
+        if self._attrsNS is None:
+            return False
         return (namespaceURI, localName) in self._attrsNS
 
     def getElementsByTagName(self, name):
@@ -853,6 +875,7 @@ class Element(Node):
             writer.write("/>%s"%(newl))
 
     def _get_attributes(self):
+        self._ensure_attributes()
         return NamedNodeMap(self._attrs, self._attrsNS, self)
 
     def hasAttributes(self):
@@ -890,6 +913,7 @@ defproperty(Element, "localName",
 
 def _set_attribute_node(element, attr):
     _clear_id_cache(element)
+    element._ensure_attributes()
     element._attrs[attr.name] = attr
     element._attrsNS[(attr.namespaceURI, attr.localName)] = attr