Skip to content

xml.etree.ElementTree: file source must be binary for non-UTF-8 encodings #99064

Closed

Description

@coproc

Documentation

In the documentation for xml.etree.ElementTree.parse it says for the first argument source: "... source is a filename or file object containing XML data. ..."

But for file objects this does not work in all (expected) cases. A hint like the following is missing:

For file objects containing XML data with non-ASCII and non-UTF-8 encoding (e.g. ISO 8859-1), the file must have been opened in binary mode.

Otherwise (if opening the file in ASCII mode, regardless of the specified encoding) non-ASCII characters are not read correctly. (see this question on stackoverflow and also the attached files in test_parseXml.zip for reproducing the problem)

Here is an excerpt of the attached test code:

import xml

# ok
with open('test_ISO-8859-1.xml', 'rb') as fileInBinary:
    root = xml.etree.ElementTree.parse(fileInBinary).getroot()
print(root.attrib['attributeWithUmlauts'])

# garbage
with open('test_ISO-8859-1.xml', 'r', encoding='ISO-8859-1') as fileInAscii:
    root = xml.etree.ElementTree.parse(fileInAscii).getroot()
print(root.attrib['attributeWithUmlauts'])

giving the following output:

äöü
äöü

Linked PRs

Activity

  1. added
    docsDocumentation in the Doc dir
    on Nov 3, 2022
  2. added a commit that references this issue on Sep 10, 2024
  3. vstinner commented on Oct 16, 2024

    @vstinner
    Member

    It's unclear to me which encodings should emit a warning or not. For example:

    • No warning: ASCII, UTF-8?
    • Warning: ISO-8859-1, ISO-8859-15, ShiftJIS, Big5, UTF-16, etc.?
  4. added
    3.13only security fixes
    3.14bugs and security fixes
    3.15bugs and security fixes
    3.16new features, bugs and security fixes
    type-bugAn unexpected behavior, bug, or error
    and removed
    docsDocumentation in the Doc dir
    on Aug 31, 2026
  5. serhiy-storchaka commented on Aug 31, 2026

    @serhiy-storchaka
    Member

    This is not a documentation issue. ElementTree.parse() is simply wrong here, and only in the C accelerator; every other way of parsing the same text is correct:

    >>> doc = '<?xml version="1.0" encoding="ISO-8859-1"?><r a="äöü"/>'
    >>> ET.parse(io.StringIO(doc)).getroot().get('a')
    'äöü'
    >>> ET.parse(io.StringIO(doc), ET.XMLParser()).getroot().get('a')
    'äöü'
    >>> ET.fromstring(doc).get('a')
    'äöü'

    XMLParser.feed() encodes str data as UTF-8 and calls XML_SetEncoding(parser, "utf-8"), so the encoding declared in the document, which no longer applies to already decoded text, is ignored. _parse_whole(), the fast path which parse() uses when no parser is given, does the same encoding but not the override. It got its handling of str in 2012 (bpo-14246), and the override was added to feed() in 2013 (bpo-16986) without touching it.

    PR #156734 adds the same override there. @vstinner, this answers your question about which encodings should warn: none of them. The text is already decoded by the file object, so its declaration is irrelevant by that point, and there is nothing left to warn about. A text source declaring UTF-16 or UTF-32 also stops raising ParseError, matching feed().

  6. added a commit that references this issue on Aug 31, 2026
  7. added 2 commits that reference this issue on Aug 31, 2026
  8. added a commit that references this issue on Sep 12, 2026
  9. added a commit that references this issue on Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13only security fixes3.14bugs and security fixes3.15bugs and security fixes3.16new features, bugs and security fixestopic-XMLtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions