Stefan Behnel added the comment:
@gene_wood: that's unrelated. This ticket is about attributes being rejected
incorrectly.
Fixing the example of the OP:
>>> from xml.etree.ElementTree import *
>>> svg = ElementTree(XML("""
... <svg width="12cm" height="4cm" viewBox="0 0 1200 400"
xmlns="http://www.w3.org/2000/svg" version="1.1">
... <rect x="1" y="1" width="1198" height="398" fill="none" stroke="blue"
stroke-width="2" />
... </svg>
... """))
>>> tostring(svg.getroot()) # formatting is mine
b'<svg:svg xmlns:svg="http://www.w3.org/2000/svg" height="4cm" version="1.1"
viewBox="0 0 1200 400" width="12cm">\n
<svg:rect fill="none" height="398" stroke="blue" stroke-width="2"
width="1198" x="1" y="1" />\n
</svg:svg>'
>>> svg.write('simple_new.svg',encoding='UTF-8',default_namespace='http://www.w3.org/2000/svg')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.3/xml/etree/ElementTree.py", line 826, in write
qnames, namespaces = _namespaces(self._root, default_namespace)
File "/usr/lib/python3.3/xml/etree/ElementTree.py", line 942, in _namespaces
add_qname(key)
File "/usr/lib/python3.3/xml/etree/ElementTree.py", line 920, in add_qname
"cannot use non-qualified names with "
ValueError: cannot use non-qualified names with default_namespace option
>>> svg.write('simple_new.svg',encoding='UTF-8')
>>>
So, it works without namespace defaulting and fails with an incorrect error
when a default namespace is provided. Clearly a bug.
Regarding the proposed patch: it looks like the right thing to do in general,
but it has a relatively high code impact. I would prefer a patch with lower
churn. One thing that could be tried is to use only one tag cache dict and
extend the key from the plain tag to (tag, is_attribute). Might have a
performance impact on the already slow serialiser, though. In any case, both
approaches are quite wasteful, because they duplicate the entire
namespace-prefix mapping just because there might be a single namespace that
behaves differently for atributes. An alternative could be to split the *value*
of the mapping in two: (element_prefix, attribute_prefix). This would keep the
overhead at serialisation low, with only slightly more work when building the
mapping. At first sight, I like that idea better.
This code returns a list in one case and a set-like view in another (Py3):
+ if default_namespace:
+ prefixes_list = [ (default_namespace, "") ]
+ prefixes_list.extend(namespaces.items())
+ else:
+ prefixes_list = namespaces.items()
I can't see the need for this change. Why can't the default namespace be stored
in the namespaces dict right from the start, as it was before?
As a minor nitpick, this lambda based sort key:
key=lambda x: x[1]): # sort on prefix
is better expressed using operator.itemgetter(1).
I'd also rename the "defaultable" flag to "is_attribute" and pass it as keyword
argument (bare boolean parameters are unreadable in function calls).
Given the impact of this change, I'd also suggest not applying it to Py2.x
anymore.
----------
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue17088>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com