From 04cefb457cfb22e9bd0707897b33aa9202fd7df7 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 1 Sep 2026 12:24:58 +0300 Subject: [PATCH 1/4] gh-156765: Fix inaccuracies in the ElementTree documentation The parser argument of iterparse() is an instance of XMLParser or its subclass, not a subclass. feed() accepts a string as well as encoded data. Bytes are no longer said to be supported for the element tag, the attribute names and values and the text of a comment: they are either rejected by the serializer or written as a repr. --- Doc/library/xml.etree.elementtree.rst | 28 +++++++++++++-------------- Lib/xml/etree/ElementTree.py | 3 --- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 310ccd651e18c7e..4ddcba93f09319b 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -551,10 +551,9 @@ Functions .. function:: Comment(text=None) Comment element factory. This factory function creates a special element - that will be serialized as an XML comment by the standard serializer. The - comment string can be either a bytestring or a Unicode string. *text* is a - string containing the comment string. Returns an element instance - representing a comment. + that will be serialized as an XML comment by the standard serializer. + *text* is a string containing the comment string. + Returns an element instance representing a comment. Note that :class:`XMLParser` skips over comments in the input instead of creating comment objects for them. An :class:`ElementTree` will @@ -622,9 +621,9 @@ Functions (the "ns" events are used to get detailed namespace information). If *events* is omitted, only ``"end"`` events are reported. *parser* is an optional parser instance. If not given, the standard - :class:`XMLParser` parser is used. *parser* must be a subclass of - :class:`XMLParser` and can only use the default :class:`TreeBuilder` as a - target. Returns an :term:`iterator` providing ``(event, elem)`` pairs; + :class:`XMLParser` parser is used. *parser* must be an instance of + :class:`XMLParser` or its subclass and can only use the default + :class:`TreeBuilder` as a target. Returns an :term:`iterator` providing ``(event, elem)`` pairs; it has a ``root`` attribute that references the root element of the resulting XML tree once *source* is fully read. The iterator has the :meth:`!close` method that closes the internal @@ -696,8 +695,7 @@ Functions Subelement factory. This function creates an element instance, and appends it to an existing element. - The element name, attribute names, and attribute values can be either - bytestrings or Unicode strings. *parent* is the parent element. *tag* is + *parent* is the parent element. *tag* is the subelement name. *attrib* is an optional dictionary, containing element attributes. *extra* contains additional attributes, given as keyword arguments. Returns an element instance. @@ -888,8 +886,7 @@ Element Objects Element class. This class defines the Element interface, and provides a reference implementation of this interface. - The element name, attribute names, and attribute values can be either - bytestrings or Unicode strings. *tag* is the element name. *attrib* is + *tag* is the element name. *attrib* is an optional dictionary, containing element attributes. *extra* contains additional attributes, given as keyword arguments. @@ -1296,8 +1293,7 @@ TreeBuilder Objects .. method:: data(data) - Adds text to the current element. *data* is a string. This should be - either a bytestring, or a Unicode string. + Adds text to the current element. *data* is a string. .. method:: end(tag) @@ -1400,7 +1396,8 @@ XMLParser Objects .. method:: feed(data) - Feeds data to the parser. *data* is encoded data. + Feeds data to the parser. *data* is a string + or encoded data (:class:`bytes` or a :term:`bytes-like object`). .. method:: flush() @@ -1479,7 +1476,8 @@ XMLPullParser Objects .. method:: feed(data) - Feed the given bytes data to the parser. + Feed the given data to the parser. *data* is a string + or encoded data (:class:`bytes` or a :term:`bytes-like object`). .. method:: flush() diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index 951540eb9f45e90..3167c686ceade8e 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -129,9 +129,6 @@ class Element: want to check if an element is truly empty, you should check BOTH its length AND its text attribute. - The element tag, attribute names, and attribute values can be either - bytes or strings. - *tag* is the element name. *attrib* is an optional dictionary containing element attributes. *extra* are additional element attributes given as keyword arguments. From f4eee16be9439d86a441d4f73e216113f87fac2e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 1 Sep 2026 15:29:59 +0300 Subject: [PATCH 2/4] Rewrap the description of the parser argument of iterparse() --- Doc/library/xml.etree.elementtree.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 4ddcba93f09319b..815e8bb694cd0e1 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -620,10 +620,11 @@ Functions ``"pi"``, ``"start-ns"`` and ``"end-ns"`` (the "ns" events are used to get detailed namespace information). If *events* is omitted, only ``"end"`` events are reported. - *parser* is an optional parser instance. If not given, the standard - :class:`XMLParser` parser is used. *parser* must be an instance of - :class:`XMLParser` or its subclass and can only use the default - :class:`TreeBuilder` as a target. Returns an :term:`iterator` providing ``(event, elem)`` pairs; + *parser* is an optional parser instance. + If not given, the standard :class:`XMLParser` parser is used. + *parser* must be an instance of :class:`XMLParser` or its subclass + and can only use the default :class:`TreeBuilder` as a target. + Returns an :term:`iterator` providing ``(event, elem)`` pairs; it has a ``root`` attribute that references the root element of the resulting XML tree once *source* is fully read. The iterator has the :meth:`!close` method that closes the internal From d502d735dbf3fc649e1f9cd44682cfb23f29f040 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 1 Sep 2026 18:40:58 +0300 Subject: [PATCH 3/4] Fix the description of Element.keys() and Element.items() They do not return a list in the Python implementation, which returns dict views. And the attributes are no longer returned in an arbitrary order: the attrib dict preserves the insertion order. --- Doc/library/xml.etree.elementtree.rst | 6 ++---- Lib/xml/etree/ElementTree.py | 12 ++++-------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 815e8bb694cd0e1..50886f195995c1e 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -956,14 +956,12 @@ Element Objects .. method:: items() - Returns the element attributes as a sequence of (name, value) pairs. The - attributes are returned in an arbitrary order. + Returns the element attributes as (name, value) pairs. .. method:: keys() - Returns the elements attribute names as a list. The names are returned - in an arbitrary order. + Returns the element attribute names. .. method:: set(key, value) diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index 3167c686ceade8e..6727ca22f6b3b77 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -356,21 +356,17 @@ def set(self, key, value): self.attrib[key] = value def keys(self): - """Get list of attribute names. + """Get attribute names. - Names are returned in an arbitrary order, just like an ordinary - Python dict. Equivalent to attrib.keys() + Equivalent to attrib.keys() """ return self.attrib.keys() def items(self): - """Get element attributes as a sequence. + """Get element attributes as (name, value) pairs. - The attributes are returned in arbitrary order. Equivalent to - attrib.items(). - - Return a list of (name, value) tuples. + Equivalent to attrib.items(). """ return self.attrib.items() From 26cadbb5b452b2fa550705f92791e636e2a32981 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 2 Sep 2026 19:43:59 +0300 Subject: [PATCH 4/4] Document what can be the element name, the attributes and the text They are strings or QName instances, and the text and the tail can also be None. The element name can also be Comment, ProcessingInstruction or None, and the attribute value can be None for the HTML method. --- Doc/library/xml.etree.elementtree.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 50886f195995c1e..21a7bf4cd48a759 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -891,6 +891,18 @@ Element Objects an optional dictionary, containing element attributes. *extra* contains additional attributes, given as keyword arguments. + The element name and the attribute names and values are strings or + :class:`QName` instances, and the text and the tail are strings or + ``None``. + The element name can also be :func:`Comment` or + :func:`ProcessingInstruction`, which are used for special elements. + If it is ``None``, the element itself is not serialized: only its text + and its children are written, and its attributes are ignored. + This can be used for a fragment which contains several elements. + With ``method="html"`` the attribute value can also be ``None``, + which produces an empty attribute (such as ``checked``). + Other objects can be stored in the tree, but they cannot be serialized. + .. versionchanged:: 3.15 *attrib* can now be a :class:`frozendict`.