Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 6 additions & 3 deletions Doc/library/xml.sax.reader.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,16 @@ The :class:`XMLReader` interface supports the following methods:

Process an input source, producing SAX events. The *source* object can be a
system identifier (a string identifying the input source -- typically a file
name or a URL), a file-like object, or an :class:`InputSource` object. When
:meth:`parse` returns, the input is completely processed, and the parser object
can be discarded or reset.
name or a URL), a :class:`~pathlib.Path` object, a file-like object or an
Comment thread
BoboTiG marked this conversation as resolved.
Outdated
:class:`InputSource` object. When :meth:`parse` returns, the input is
completely processed, and the parser object can be discarded or reset.

.. versionchanged:: 3.5
Added support of character streams.

.. versionchanged:: 3.8
Added support of :class:`~pathlib.Path` objects.


.. method:: XMLReader.getContentHandler()

Expand Down
12 changes: 12 additions & 0 deletions Lib/test/test_sax.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from io import BytesIO, StringIO
import codecs
import os.path
import pathlib
import shutil
from urllib.error import URLError
from test import support
Expand Down Expand Up @@ -182,6 +183,10 @@ def test_parse_bytes(self):
with self.assertRaises(SAXException):
self.check_parse(f)

def test_parse_path_object(self):
make_xml_file(self.data, 'utf-8', None)
self.check_parse(pathlib.Path(TESTFN))

def test_parse_InputSource(self):
# accept data without declared but with explicitly specified encoding
make_xml_file(self.data, 'iso-8859-1', None)
Expand Down Expand Up @@ -397,6 +402,13 @@ def test_string(self):
self.checkContent(prep.getByteStream(),
b"This was read from a file.")

def test_path_objects(self):
# If the source is a Path object, use it as a system ID and open it.
prep = prepare_input_source(pathlib.Path(self.file))
Comment thread
BoboTiG marked this conversation as resolved.
Outdated
self.assertIsNone(prep.getCharacterStream())
self.checkContent(prep.getByteStream(),
b"This was read from a file.")

def test_binary_file(self):
# If the source is a binary file-like object, use it as a byte
# stream.
Expand Down
2 changes: 2 additions & 0 deletions Lib/xml/sax/saxutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ def prepare_input_source(source, base=""):
"""This function takes an InputSource and an optional base URL and
returns a fully resolved InputSource object ready for reading."""

if isinstance(source, os.PathLike):
source = os.fspath(source)
if isinstance(source, str):
source = xmlreader.InputSource(source)
elif hasattr(source, "read"):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make xml.sax.parse accepting Path objects. Patch by Mickaël Schoentgen.
Comment thread
BoboTiG marked this conversation as resolved.
Outdated