Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
gh-91810: Fix regression with writing an XML declaration with encodin…
…g='unicode' (GH-93426)

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
serhiy-storchaka authored and miss-islington committed Jun 14, 2022
commit 73edebcc68aa833be8d2ac2d46f5045e9a052e27
16 changes: 3 additions & 13 deletions Lib/test/test_xml_etree.py
Original file line number Diff line number Diff line change
Expand Up @@ -3680,13 +3680,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(support.unlink, TESTFN)
Expand All @@ -3701,17 +3695,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(support.unlink, TESTFN)
Expand Down
12 changes: 5 additions & 7 deletions Lib/xml/etree/ElementTree.py
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Suppress writing an XML declaration in open files in ``ElementTree.write()``
with ``encoding='unicode'`` and ``xml_declaration=None``.