attrib cannot be copied
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
lxml |
Fix Released
|
Low
|
scoder |
Bug Description
[forwarding http://
copying Element's "attrib" attribute leads to unexpected behaviour
lxml 2.2.8
==========
$ python -c 'import lxml.etree; print lxml.etree.
{'c': 'bar', 'b': 'foo'}
$ python -c 'import lxml.etree, copy; print copy.copy(
{}
lxml 2.3.2 (and 2.3.5 and 3.0.1)
==========
$ python -c 'import lxml.etree; print lxml.etree.
{'c': 'bar', 'b': 'foo'}
$ python -c 'import lxml.etree, copy; print copy.copy(
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/
return _reconstruct(x, rv, 0)
File "/usr/lib/
y = callable(*args)
File "/usr/lib/
return cls.__new__(cls, *args)
File "lxml.etree.pyx", line 2155, in lxml.etree.
TypeError: __cinit__() takes exactly 1 positional argument (0 given)
Python : sys.version_
lxml.etree : (3, 0, 1, 0)
libxml used : (2, 8, 0)
libxml compiled : (2, 8, 0)
libxslt used : (1, 1, 26)
libxslt compiled : (1, 1, 26)
Changed in lxml: | |
milestone: | none → 3.1 |
Seriously - I'm sure no-one has *ever* tried this before. What I usually do is to call dict() on the attrib value, which is way more obvious and explicit and works just fine:
$ python -c 'import lxml.etree; print lxml.etree. fromstring( """<a b="foo" c="bar" />""").attrib' etree.fromstrin g("""<a b="foo" c="bar" />""").attrib)'
{'c': 'bar', 'b': 'foo'}
$ python -c 'import lxml.etree; print dict(lxml.
{'c': 'bar', 'b': 'foo'}
I'm not even sure what copy(Attrib) should return. It certainly can't return a new attrib proxy object, that wouldn't make sense at all.
For comparison, here's what CPython 3.4 gives me in a similar case, when requesting a copy of a dict items view:
>>> import copy 4-opt/lib/ python3. 4/copy. py", line 97, in copy 4-opt/lib/ python3. 4/copy. py", line 287, in _reconstruct 4-opt/lib/ python3. 4/copyreg. py", line 88, in __newobj__ __new__ (dict_items) is not safe, use dict_items. __new__ ()
>>> copy.copy(dict(a=1, b=2).items())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/python3.
return _reconstruct(x, rv, 0)
File "/opt/python3.
y = callable(*args)
File "/opt/python3.
return cls.__new__(cls, *args)
TypeError: object.
Maybe mapping __copy__() to a call to dict() would be a reasonable compromise, just to keep it from failing...