Skip to content

gh-158978: Fix cloning of DOM Level 1 nodes in xml.dom.minidom - #158987

Open
sricursion wants to merge 2 commits into
python:mainfrom
sricursion:minidom-clone-dom1-names
Open

sricursion wants to merge 2 commits into
python:mainfrom
sricursion:minidom-clone-dom1-names

Conversation

@sricursion

@sricursion sricursion commented Oct 7, 2026 •

Copy link
Copy Markdown

Node.cloneNode() and Document.importNode() raise NamespaceErr for DOM Level 1 nodes that have a colon in the name, for example createElement("svg:rect"), setAttribute("xmlns:xsi", ...), createAttribute("a:b"), or any node of a document parsed with namespaces disabled. _clone_node() rebuilt every element and attribute with createElementNS(), setAttributeNS() and createAttributeNS(), and since gh-156665 those reject a prefixed name in no namespace. The same applies to setAttribute("xmlns", ...), which is rejected as the xmlns attribute in the wrong namespace. This is a regression in 3.16 only; 3.15 and earlier clone these nodes without error. Nodes without a namespace are now cloned with the DOM Level 1 factory methods createElement(), setAttribute() and createAttribute(), which only check the name, and namespaced nodes still with the NS variants, so the clone keeps the original's prefix.

There is no NEWS entry, since the entry for gh-156665 already describes the resulting behaviour.

cloneNode() and importNode() created the clones with createElementNS(),
setAttributeNS() and createAttributeNS(), which now reject a prefixed
name in no namespace. Create the Element and Attr nodes directly
instead.
@python-cla-bot

python-cla-bot Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

@bedevere-app

bedevere-app Bot commented Oct 7, 2026

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@serhiy-storchaka

Copy link
Copy Markdown
Member

Thank you for the fix, but I would not bypass the factory methods of the document. All other branches of _clone_node() use them, and their purpose is that an implementation or a subclass of Document can create instances of its own classes.

A DOM Level 1 node has no namespace, so it can be cloned with the DOM Level 1 methods, which only check the name: createElement() and setAttribute() for an element and its attributes, createAttribute() for an attribute node, and the NS variants when namespaceURI is not None.

This also makes the clone more faithful: for createElement("svg:rect") the original has prefix=None, but the clone has prefix='svg' both before and after your change.

Please add a NEWS entry.

@serhiy-storchaka

Copy link
Copy Markdown
Member

About the NEWS entry: it is not necessary, because gh-156665 is only in 3.16, and its own entry describes the resulting behaviour. It was already in an alpha release, so an entry is acceptable, but up to you.

Clone nodes without a namespace with createElement(), setAttribute()
and createAttribute(), and namespaced nodes with the NS variants, so
that a Document subclass can create its own node classes and the clone
keeps the prefix of the original.  The tests now compare the names of
the clone with those of the original.
@sricursion

Copy link
Copy Markdown
Author

Thanks, that's better. _clone_node() now uses createElement(), setAttribute() and createAttribute() when namespaceURI is None, and the NS factory methods otherwise, so the clone keeps prefix=None like the original and subclasses of Document get their own classes. The tests now compare the clone's nodeName, prefix, localName and namespaceURI with the original's. I left it without a NEWS entry, since the gh-156665 entry covers the behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants