From 61c30ec0802df883dbfbcc5e8fa1de8048580f5a Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 19 Jul 2019 20:47:01 +0200 Subject: [PATCH 1/4] Fix the formatting in the documentation of the tostring() functions. --- Doc/library/xml.etree.elementtree.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index c4667315793e4c..e42b994d85a6e0 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -659,7 +659,7 @@ Functions .. function:: tostring(element, encoding="us-ascii", method="xml", *, \ - xml_declaration=None, default_namespace=None, + xml_declaration=None, default_namespace=None, \ short_empty_elements=True) Generates a string representation of an XML element, including all @@ -679,7 +679,7 @@ Functions .. function:: tostringlist(element, encoding="us-ascii", method="xml", *, \ - xml_declaration=None, default_namespace=None, + xml_declaration=None, default_namespace=None, \ short_empty_elements=True) Generates a string representation of an XML element, including all From af204fd4af15ec3ff97ee50d3fa50709ad2bd5d0 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 19 Jul 2019 20:49:14 +0200 Subject: [PATCH 2/4] bpo-34160: Document that the tostring() and tostringlist() functions also preserve the attribute order now. --- Doc/library/xml.etree.elementtree.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index e42b994d85a6e0..d7f56e899d7a00 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -677,6 +677,10 @@ Functions .. versionadded:: 3.8 The *xml_declaration* and *default_namespace* parameters. + .. versionchanged:: 3.8 + The :func:`tostring` function now preserves the attribute order + specified by the user. + .. function:: tostringlist(element, encoding="us-ascii", method="xml", *, \ xml_declaration=None, default_namespace=None, \ @@ -700,6 +704,10 @@ Functions .. versionadded:: 3.8 The *xml_declaration* and *default_namespace* parameters. + .. versionchanged:: 3.8 + The :func:`tostringlist` function now preserves the attribute order + specified by the user. + .. function:: XML(text, parser=None) From 7e85ceb34e7bf96a37a48612be9a721825d6aec4 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 19 Jul 2019 21:34:56 +0200 Subject: [PATCH 3/4] bpo-34160: Add an explanation of how users should deal with the attribute order. --- Doc/library/xml.etree.elementtree.rst | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index d7f56e899d7a00..768140990c4a70 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -938,6 +938,36 @@ Element Objects if element is None: print("element not found") + Prior to Python 3.8, the serialisation order of the attributes of Elements + was artificially made predictable by sorting the attributes by their name. + Based on the now guaranteed ordering of dicts, this arbitrary reordering + was removed in Python 3.8 to preserve the order in which attributes were + originally parsed or created by user code. + + In general, user code should try not to depend on a specific ordering of + attributes, given that the `XML Information Set + `_ explicitly excludes the attribute + order from conveying information. Code should be prepared to deal with + any ordering on input. In cases where deterministic XML output is required, + e.g. for cryptographic signing or test data sets, canonical serialisation + is available with the :func:`canonicalize` function. + + In cases where canonical output is not applicable but a specific attribute + order is still desirable on output, code should aim for creating the + attributes directly in the desired order, to avoid perceptual mismatches + for readers of the code. In cases where this is difficult to achieve, a + recipe like the following can be applied prior to serialisation to enforce + an order independently from the Element creation:: + + def reorder_attributes(root): + for el in root.iter(): + attrib = el.attrib + if len(attrib) > 1: + # adjust attribute order, e.g. by sorting + attribs = sorted(attrib.items()) + attrib.clear() + attrib.update(attribs) + .. _elementtree-elementtree-objects: From 6bb5d26541806998bd43b559caaf78643529fa31 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Wed, 24 Jul 2019 20:04:59 +0200 Subject: [PATCH 4/4] bpo-34160: Clarify that "attribute" refers to XML attributes and not Python object attributes. --- Doc/library/xml.etree.elementtree.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 768140990c4a70..9f46755c2685d1 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -938,11 +938,11 @@ Element Objects if element is None: print("element not found") - Prior to Python 3.8, the serialisation order of the attributes of Elements - was artificially made predictable by sorting the attributes by their name. - Based on the now guaranteed ordering of dicts, this arbitrary reordering - was removed in Python 3.8 to preserve the order in which attributes were - originally parsed or created by user code. + Prior to Python 3.8, the serialisation order of the XML attributes of + elements was artificially made predictable by sorting the attributes by + their name. Based on the now guaranteed ordering of dicts, this arbitrary + reordering was removed in Python 3.8 to preserve the order in which + attributes were originally parsed or created by user code. In general, user code should try not to depend on a specific ordering of attributes, given that the `XML Information Set