diff options
-rw-r--r-- | Doc/library/pathlib.rst | 23 | ||||
-rw-r--r-- | Lib/pathlib.py | 22 | ||||
-rw-r--r-- | Lib/test/test_pathlib.py | 11 | ||||
-rw-r--r-- | Misc/NEWS | 14 |
4 files changed, 56 insertions, 14 deletions
diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index ff5196d..ca44a65 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -31,12 +31,6 @@ Pure paths are useful in some special cases; for example: 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 @@ we also call *flavours*: 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 @@ we also call *flavours*: 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 @@ The slash operator helps create child paths, similarly to :func:`os.path.join`:: >>> '/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 index 1480e2f..a06676f 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -634,13 +634,16 @@ class PurePath(object): 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 @@ class PurePath(object): 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 @@ class PurePath(object): 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 index fbbd448..2f2ba3c 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -190,13 +190,18 @@ class _BasePurePathTest(object): 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 @@ class _BasePurePathTest(object): 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) @@ -10,6 +10,8 @@ What's New in Python 3.6.0 alpha 2 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 @@ Core and Builtins 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 @@ Build 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. |