Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gh-61290: Fix serializing attributes with the default_namespace option - #156747

Merged
serhiy-storchaka merged 3 commits into
python:mainfrom
serhiy-storchaka:gh-61290-default-namespace-attrs
Sep 13, 2026
Merged

gh-61290: Fix serializing attributes with the default_namespace option#156747
serhiy-storchaka merged 3 commits into
python:mainfrom
serhiy-storchaka:gh-61290-default-namespace-attrs

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented Aug 31, 2026

Copy link
Copy Markdown
Member

Serialization with the default_namespace option failed for any attribute without a namespace:

>>> svg = ET.XML('<svg xmlns="http://www.w3.org/2000/svg"><rect fill="none"/></svg>')
>>> ET.tostring(svg, default_namespace='http://www.w3.org/2000/svg')
ValueError: cannot use non-qualified names with default_namespace option

But a default namespace declaration does not apply to attribute names (Namespaces in XML, 6.2), so an unqualified attribute name can be written as is. For the same reason a qualified attribute name always needs a prefix, even if it is in the default namespace, and its namespace has to be declared twice:

>>> e = ET.Element('{uri}svg', {'{uri}id': 'a'})
>>> ET.tostring(e, encoding='unicode', default_namespace='uri')
'<svg xmlns="uri" xmlns:ns1="uri" ns1:id="a" />'

lxml serializes it the same way. Attribute names are now encoded separately from element names, and the namespaces table maps prefixes to URIs, because one URI can need both the default declaration and a prefixed one.

This also fixes gh-113581, the same bug seen from the other side: a qualified attribute name in the default namespace was written without a prefix, so its namespace was silently lost when the document was parsed back.

… option

The default namespace declaration does not apply to attribute names, so an
unqualified attribute name can be written as is, and a qualified attribute
name always needs a prefix, even if it is in the default namespace.  They
are now encoded separately from element names, and the namespaces table maps
prefixes to URIs, because a URI can need both the default declaration and a
prefixed one.
register_namespace("", uri) still makes it the default namespace, unless the
default_namespace option is used for other uri.  Serializing such tree no
longer produces two xmlns attributes (pythongh-118416).
…ult-namespace-attrs

# Conflicts:
#	Lib/test/test_xml_etree.py
@serhiy-storchaka
serhiy-storchaka enabled auto-merge (squash) September 13, 2026 17:06
@serhiy-storchaka
serhiy-storchaka merged commit ce32912 into python:main Sep 13, 2026
54 checks passed
@serhiy-storchaka
serhiy-storchaka deleted the gh-61290-default-namespace-attrs branch September 13, 2026 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ElementTree.tostring(..., default_namespace=...) incorrectly strips namespace from attributes

1 participant