aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/pathlib.py22
-rw-r--r--Lib/test/test_pathlib.py11
2 files changed, 27 insertions, 6 deletions
diff --git a/Lib/pathlib.py b/Lib/pathlib.py
index 1480e2fc71a..a06676fbe4f 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 fbbd448f65d..2f2ba3cbfc7 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)