[Python-checkins] [3.8] bpo-34160: explain how to deal with attribute order in ElementTree (GH-14867) (GH-14935)

Stefan Behnel webhook-mailer at python.org
Wed Jul 24 14:33:06 EDT 2019


https://github.com/python/cpython/commit/63673916464bace8e2147357395fdf3497967ecb
commit: 63673916464bace8e2147357395fdf3497967ecb
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Stefan Behnel <stefan_ml at behnel.de>
date: 2019-07-24T20:32:56+02:00
summary:

[3.8] bpo-34160: explain how to deal with attribute order in ElementTree (GH-14867) (GH-14935)

* Fix the formatting in the documentation of the tostring() functions.

* bpo-34160: Document that the tostring() and tostringlist() functions also preserve the attribute order now.

* bpo-34160: Add an explanation of how users should deal with the attribute order.
(cherry picked from commit a3697db0102b9b6747fe36009e42f9b08f0c1ea8)

Co-authored-by: Stefan Behnel <stefan_ml at behnel.de>

files:
M Doc/library/xml.etree.elementtree.rst

diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst
index c4667315793e..9f46755c2685 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
@@ -677,9 +677,13 @@ 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,
+                           xml_declaration=None, default_namespace=None, \
                            short_empty_elements=True)
 
    Generates a string representation of an XML element, including all
@@ -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)
 
@@ -930,6 +938,36 @@ Element Objects
      if element is None:
          print("element not found")
 
+   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
+   <https://www.w3.org/TR/xml-infoset/>`_ 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:
 



More information about the Python-checkins mailing list