[Python-checkins] cpython: Issue #27186: Add os.PathLike support to pathlib.

brett.cannon python-checkins at python.org
Fri Jun 10 15:34:06 EDT 2016


https://hg.python.org/cpython/rev/a5a013ca5687
changeset: 101855:a5a013ca5687
user: Brett Cannon <brett at python.org>
date: Fri Jun 10 12:20:49 2016 -0700
summary:
 Issue #27186: Add os.PathLike support to pathlib.
This adds support both to pathlib.PurePath's constructor as well as
implementing __fspath__(). This removes the provisional status for
pathlib.
Initial patch by Dusty Phillips.
files:
 Doc/library/pathlib.rst | 23 ++++++++++++++++-------
 Lib/pathlib.py | 22 ++++++++++++++++------
 Lib/test/test_pathlib.py | 11 +++++++++++
 Misc/NEWS | 14 +++++++++++++-
 4 files changed, 56 insertions(+), 14 deletions(-)
diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst
--- a/Doc/library/pathlib.rst
+++ b/Doc/library/pathlib.rst
@@ -31,12 +31,6 @@
 accessing the OS. In this case, instantiating one of the pure classes may be
 useful since those simply don't have any OS-accessing operations.
 
-.. note::
- This module has been included in the standard library on a
- :term:`provisional basis <provisional package>`. Backwards incompatible
- changes (up to and including removal of the package) may occur if deemed
- necessary by the core developers.
-
 .. seealso::
 :pep:`428`: The pathlib module -- object-oriented filesystem paths.
 
@@ -107,7 +101,8 @@
 PurePosixPath('setup.py')
 
 Each element of *pathsegments* can be either a string representing a
- path segment, or another path object::
+ path segment, an object implementing the :class:`os.PathLike` interface
+ which returns a string, or another path object::
 
 >>> PurePath('foo', 'some/path', 'bar')
 PurePosixPath('foo/some/path/bar')
@@ -148,6 +143,12 @@
 to ``PurePosixPath('bar')``, which is wrong if ``foo`` is a symbolic link
 to another directory)
 
+ Pure path objects implement the :class:`os.PathLike` interface, allowing them
+ to be used anywhere the interface is accepted.
+
+ .. versionchanged:: 3.6
+ Added support for the :class:`os.PathLike` interface.
+
 .. class:: PurePosixPath(*pathsegments)
 
 A subclass of :class:`PurePath`, this path flavour represents non-Windows
@@ -212,6 +213,14 @@
 >>> '/usr' / q
 PurePosixPath('/usr/bin')
 
+A path object can be used anywhere an object implementing :class:`os.PathLike`
+is accepted::
+
+ >>> import os
+ >>> p = PurePath('/etc')
+ >>> os.fspath(p)
+ '/etc'
+
 The string representation of a path is the raw filesystem path itself
 (in native form, e.g. with backslashes under Windows), which you can
 pass to any function taking a file path as a string::
diff --git a/Lib/pathlib.py b/Lib/pathlib.py
--- a/Lib/pathlib.py
+++ b/Lib/pathlib.py
@@ -634,13 +634,16 @@
 for a in args:
 if isinstance(a, PurePath):
 parts += a._parts
- elif isinstance(a, str):
- # Force-cast str subclasses to str (issue #21127)
- parts.append(str(a))
 else:
- raise TypeError(
- "argument should be a path or str object, not %r"
- % type(a))
+ a = os.fspath(a)
+ if isinstance(a, str):
+ # Force-cast str subclasses to str (issue #21127)
+ parts.append(str(a))
+ else:
+ raise TypeError(
+ "argument should be a str object or an os.PathLike "
+ "object returning str, not %r"
+ % type(a))
 return cls._flavour.parse_parts(parts)
 
 @classmethod
@@ -693,6 +696,9 @@
 self._parts) or '.'
 return self._str
 
+ def __fspath__(self):
+ return str(self)
+
 def as_posix(self):
 """Return the string representation of the path with forward (/)
 slashes."""
@@ -943,6 +949,10 @@
 return False
 return True
 
+# Can't subclass os.PathLike from PurePath and keep the constructor
+# optimizations in PurePath._parse_args().
+os.PathLike.register(PurePath)
+
 
 class PurePosixPath(PurePath):
 _flavour = _posix_flavour
diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py
--- a/Lib/test/test_pathlib.py
+++ b/Lib/test/test_pathlib.py
@@ -190,13 +190,18 @@
 P = self.cls
 p = P('a')
 self.assertIsInstance(p, P)
+ class PathLike:
+ def __fspath__(self):
+ return "a/b/c"
 P('a', 'b', 'c')
 P('/a', 'b', 'c')
 P('a/b/c')
 P('/a/b/c')
+ P(PathLike())
 self.assertEqual(P(P('a')), P('a'))
 self.assertEqual(P(P('a'), 'b'), P('a/b'))
 self.assertEqual(P(P('a'), P('b')), P('a/b'))
+ self.assertEqual(P(P('a'), P('b'), P('c')), P(PathLike()))
 
 def _check_str_subclass(self, *args):
 # Issue #21127: it should be possible to construct a PurePath object
@@ -384,6 +389,12 @@
 parts = p.parts
 self.assertEqual(parts, (sep, 'a', 'b'))
 
+ def test_fspath_common(self):
+ P = self.cls
+ p = P('a/b')
+ self._check_str(p.__fspath__(), ('a/b',))
+ self._check_str(os.fspath(p), ('a/b',))
+
 def test_equivalences(self):
 for k, tuples in self.equivalences.items():
 canon = k.replace('/', self.sep)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@
 Core and Builtins
 -----------------
 
+- Issue #27186: Add support for os.PathLike objects to open() (part of PEP 519).
+
 - Issue #27066: Fixed SystemError if a custom opener (for open()) returns a
 negative number without setting an exception.
 
@@ -36,6 +38,14 @@
 Library
 -------
 
+- Issue #27186: Add os.PathLike support to pathlib, removing its provisional
+ status (part of PEP 519).
+
+- Issue #27186: Add support for os.PathLike objects to os.fsencode() and
+ os.fsdecode() (part of PEP 519).
+
+- Issue #27186: Introduce os.PathLike and os.fspath() (part of PEP 519).
+
 - A new version of typing.py provides several new classes and
 features: @overload outside stubs, Reversible, DefaultDict, Text,
 ContextManager, Type[], NewType(), TYPE_CHECKING, and numerous bug
@@ -198,12 +208,14 @@
 Misc
 ----
 
-- Issue #17500, and https://github.com/python/pythondotorg/issues/945: Remove 
+- Issue #17500, and https://github.com/python/pythondotorg/issues/945: Remove
 unused and outdated icons.
 
 C API
 -----
 
+- Issue #27186: Add the PyOS_FSPath() function (part of PEP 519).
+
 - Issue #26282: PyArg_ParseTupleAndKeywords() now supports positional-only
 parameters.
 
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /