bpo-34160: Preserve user specified order of Element attributes (GH-10163)
This commit is contained in:
parent
18d57b4d62
commit
e3685fd5fd
|
@ -489,6 +489,10 @@ Functions
|
||||||
|
|
||||||
*elem* is an element tree or an individual element.
|
*elem* is an element tree or an individual element.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.8
|
||||||
|
The :func:`dump` function now preserves the attribute order specified
|
||||||
|
by the user.
|
||||||
|
|
||||||
|
|
||||||
.. function:: fromstring(text)
|
.. function:: fromstring(text)
|
||||||
|
|
||||||
|
@ -947,6 +951,10 @@ ElementTree Objects
|
||||||
.. versionadded:: 3.4
|
.. versionadded:: 3.4
|
||||||
The *short_empty_elements* parameter.
|
The *short_empty_elements* parameter.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.8
|
||||||
|
The :meth:`write` method now preserves the attribute order specified
|
||||||
|
by the user.
|
||||||
|
|
||||||
|
|
||||||
This is the XML file that is going to be manipulated::
|
This is the XML file that is going to be manipulated::
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
# For this purpose, the module-level "ET" symbol is temporarily
|
# For this purpose, the module-level "ET" symbol is temporarily
|
||||||
# monkey-patched when running the "test_xml_etree_c" test suite.
|
# monkey-patched when running the "test_xml_etree_c" test suite.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import copy
|
import copy
|
||||||
import functools
|
import functools
|
||||||
import html
|
import html
|
||||||
|
@ -1044,6 +1045,25 @@ class ElementTreeTest(unittest.TestCase):
|
||||||
method='html')
|
method='html')
|
||||||
self.assertEqual(serialized, expected)
|
self.assertEqual(serialized, expected)
|
||||||
|
|
||||||
|
def test_dump_attribute_order(self):
|
||||||
|
# See BPO 34160
|
||||||
|
e = ET.Element('cirriculum', status='public', company='example')
|
||||||
|
with support.captured_stdout() as stdout:
|
||||||
|
ET.dump(e)
|
||||||
|
self.assertEqual(stdout.getvalue(),
|
||||||
|
'<cirriculum status="public" company="example" />\n')
|
||||||
|
|
||||||
|
def test_tree_write_attribute_order(self):
|
||||||
|
# See BPO 34160
|
||||||
|
root = ET.Element('cirriculum', status='public', company='example')
|
||||||
|
tree = ET.ElementTree(root)
|
||||||
|
f = io.BytesIO()
|
||||||
|
with contextlib.redirect_stdout(f):
|
||||||
|
tree.write(f, encoding='utf-8', xml_declaration=True)
|
||||||
|
self.assertEqual(f.getvalue(),
|
||||||
|
b"<?xml version='1.0' encoding='utf-8'?>\n"
|
||||||
|
b'<cirriculum status="public" company="example" />')
|
||||||
|
|
||||||
|
|
||||||
class XMLPullParserTest(unittest.TestCase):
|
class XMLPullParserTest(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -923,7 +923,7 @@ def _serialize_xml(write, elem, qnames, namespaces,
|
||||||
k,
|
k,
|
||||||
_escape_attrib(v)
|
_escape_attrib(v)
|
||||||
))
|
))
|
||||||
for k, v in sorted(items): # lexical order
|
for k, v in items:
|
||||||
if isinstance(k, QName):
|
if isinstance(k, QName):
|
||||||
k = k.text
|
k = k.text
|
||||||
if isinstance(v, QName):
|
if isinstance(v, QName):
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ElementTree now preserves the attribute order specified by the user.
|
Loading…
Reference in New Issue