Bug report
The documentation of register_namespace() says that ValueError is raised "if prefix is reserved or is invalid", but only the reserved form ns followed by digits is checked. Any other string is accepted, and the serializer then produces XML which is not well-formed or not namespace-well-formed:
>>> import xml.etree.ElementTree as ET
>>> def show(prefix, uri):
... ET.register_namespace(prefix, uri)
... print(ET.tostring(ET.Element(f'{{{uri}}}a', {f'{{{uri}}}k': 'v'}), encoding='unicode'))
...
>>> show('xml', 'u')
<xml:a xml:k="v" />
>>> show('foo', 'http://www.w3.org/XML/1998/namespace')
<foo:a xmlns:foo="http://www.w3.org/XML/1998/namespace" foo:k="v" />
>>> show('xmlns', 'u')
<xmlns:a xmlns:xmlns="u" xmlns:k="v" />
>>> show('a:b', 'u')
<a:b:a xmlns:a:b="u" a:b:k="v" />
>>> show('a b', 'u')
<a b:a xmlns:a b="u" a b:k="v" />
The xml prefix can only be bound to http://www.w3.org/XML/1998/namespace and no other prefix can be bound to it, xmlns cannot be used as a prefix, and a prefix must be an NCName (Namespaces in XML 1.0, sections 3 and 4). register_namespace() should raise ValueError in these cases, like it does for the reserved prefixes.
The empty prefix, which registers a global default namespace, is a separate case, see gh-118416.
Linked PRs
Bug report
The documentation of
register_namespace()says thatValueErroris raised "if prefix is reserved or is invalid", but only the reserved formnsfollowed by digits is checked. Any other string is accepted, and the serializer then produces XML which is not well-formed or not namespace-well-formed:The
xmlprefix can only be bound tohttp://www.w3.org/XML/1998/namespaceand no other prefix can be bound to it,xmlnscannot be used as a prefix, and a prefix must be an NCName (Namespaces in XML 1.0, sections 3 and 4).register_namespace()should raiseValueErrorin these cases, like it does for the reserved prefixes.The empty prefix, which registers a global default namespace, is a separate case, see gh-118416.
Linked PRs