Skip to content

Commit

Permalink
gh-91810: Fix regression with writing an XML declaration with encodin…
Browse files Browse the repository at this point in the history
…g='unicode' (GH-93426) (GH-93790)

Suppress writing an XML declaration in open files in ElementTree.write()
with encoding='unicode' and xml_declaration=None.

If file patch is passed to ElementTree.write() with encoding='unicode',
always open a new file in UTF-8.
(cherry picked from commit d7db9dc)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
  • Loading branch information
miss-islington and serhiy-storchaka committed Jun 16, 2022
1 parent 5c10c36 commit a27f3cc
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 20 deletions.
16 changes: 3 additions & 13 deletions Lib/test/test_xml_etree.py
Expand Up @@ -3739,13 +3739,7 @@ def test_write_to_filename_as_unicode(self):
tree = ET.ElementTree(ET.XML('''<site>\xf8</site>'''))
tree.write(TESTFN, encoding='unicode')
with open(TESTFN, 'rb') as f:
data = f.read()
expected = "<site>\xf8</site>".encode(encoding, 'xmlcharrefreplace')
if encoding.lower() in ('utf-8', 'ascii'):
self.assertEqual(data, expected)
else:
self.assertIn(b"<?xml version='1.0' encoding=", data)
self.assertIn(expected, data)
self.assertEqual(f.read(), b"<site>\xc3\xb8</site>")

def test_write_to_text_file(self):
self.addCleanup(os_helper.unlink, TESTFN)
Expand All @@ -3760,17 +3754,13 @@ def test_write_to_text_file(self):
tree.write(f, encoding='unicode')
self.assertFalse(f.closed)
with open(TESTFN, 'rb') as f:
self.assertEqual(f.read(), convlinesep(
b'''<?xml version='1.0' encoding='ascii'?>\n'''
b'''<site>&#248;</site>'''))
self.assertEqual(f.read(), b'''<site>&#248;</site>''')

with open(TESTFN, 'w', encoding='ISO-8859-1') as f:
tree.write(f, encoding='unicode')
self.assertFalse(f.closed)
with open(TESTFN, 'rb') as f:
self.assertEqual(f.read(), convlinesep(
b'''<?xml version='1.0' encoding='ISO-8859-1'?>\n'''
b'''<site>\xf8</site>'''))
self.assertEqual(f.read(), b'''<site>\xf8</site>''')

def test_write_to_binary_file(self):
self.addCleanup(os_helper.unlink, TESTFN)
Expand Down
12 changes: 5 additions & 7 deletions Lib/xml/etree/ElementTree.py
Expand Up @@ -731,6 +731,7 @@ def write(self, file_or_filename,
with _get_writer(file_or_filename, encoding) as (write, declared_encoding):
if method == "xml" and (xml_declaration or
(xml_declaration is None and
encoding.lower() != "unicode" and
declared_encoding.lower() not in ("utf-8", "us-ascii"))):
write("<?xml version='1.0' encoding='%s'?>\n" % (
declared_encoding,))
Expand All @@ -757,13 +758,10 @@ def _get_writer(file_or_filename, encoding):
except AttributeError:
# file_or_filename is a file name
if encoding.lower() == "unicode":
file = open(file_or_filename, "w",
errors="xmlcharrefreplace")
else:
file = open(file_or_filename, "w", encoding=encoding,
errors="xmlcharrefreplace")
with file:
yield file.write, file.encoding
encoding="utf-8"
with open(file_or_filename, "w", encoding=encoding,
errors="xmlcharrefreplace") as file:
yield file.write, encoding
else:
# file_or_filename is a file-like object
# encoding determines if it is a text or binary writer
Expand Down
@@ -0,0 +1,2 @@
Suppress writing an XML declaration in open files in ``ElementTree.write()``
with ``encoding='unicode'`` and ``xml_declaration=None``.

0 comments on commit a27f3cc

Please sign in to comment.