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.
This commit is contained in:
parent
f41b82fb19
commit
568be63248
|
@ -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::
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
14
Misc/NEWS
14
Misc/NEWS
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue