@@ -61,16 +61,17 @@ def _getAttributes(self):
61
61
return self ._element .attrib
62
62
63
63
def _setAttributes (self , attributes ):
64
- # Delete existing attributes first
65
- # XXX - there may be a better way to do this...
66
- for key in list (self ._element .attrib .keys ()):
67
- del self ._element .attrib [key ]
68
- for key , value in attributes .items ():
69
- if isinstance (key , tuple ):
70
- name = "{%s}%s" % (key [2 ], key [1 ])
71
- else :
72
- name = key
73
- self ._element .set (name , value )
64
+ el_attrib = self ._element .attrib
65
+ el_attrib .clear ()
66
+ if attributes :
67
+ # calling .items _always_ allocates, and the above truthy check is cheaper than the
68
+ # allocation on average
69
+ for key , value in attributes .items ():
70
+ if isinstance (key , tuple ):
71
+ name = "{%s}%s" % (key [2 ], key [1 ])
72
+ else :
73
+ name = key
74
+ el_attrib [name ] = value
74
75
75
76
attributes = property (_getAttributes , _setAttributes )
76
77
@@ -129,8 +130,10 @@ def insertText(self, data, insertBefore=None):
129
130
130
131
def cloneNode (self ):
131
132
element = type (self )(self .name , self .namespace )
132
- for name , value in self .attributes .items ():
133
- element .attributes [name ] = value
133
+ try :
134
+ element ._element .attrib = self ._element .attrib .copy ()
135
+ except AttributeError :
136
+ element .attributes = self .attributes
134
137
return element
135
138
136
139
def reparentChildren (self , newParent ):
0 commit comments