Skip to content

Commit 6c1131e

Browse files
committed
pythonGH-103525: Improve exception message from pathlib.PurePath()
Check that arguments are strings before calling `os.path.join()`. Also improve performance of `PurePath(PurePath(...))` while we're in the area: we now use the *unnormalized* string path of such arguments.
1 parent a6f9594 commit 6c1131e

File tree

3 files changed

+24
-16
lines changed

3 files changed

+24
-16
lines changed

Lib/pathlib.py

+20-14
Original file line numberDiff line numberDiff line change
@@ -300,18 +300,24 @@ def __reduce__(self):
300300
return (self.__class__, self.parts)
301301

302302
def __init__(self, *args):
303-
if not args:
304-
path = ''
305-
elif len(args) == 1:
306-
path = os.fspath(args[0])
303+
paths = []
304+
for arg in args:
305+
if isinstance(arg, PurePath):
306+
path = arg._raw_path
307+
else:
308+
path = os.fspath(arg)
309+
if not isinstance(path, str):
310+
raise TypeError(
311+
"argument should be a str or an os.PathLike "
312+
"object where __fspath__ returns a str, "
313+
f"not {type(path).__name__!r}")
314+
paths.append(path)
315+
if len(paths) == 0:
316+
self._raw_path = ''
317+
elif len(paths) == 1:
318+
self._raw_path = paths[0]
307319
else:
308-
path = self._flavour.join(*args)
309-
if not isinstance(path, str):
310-
raise TypeError(
311-
"argument should be a str or an os.PathLike "
312-
"object where __fspath__ returns a str, "
313-
f"not {type(path).__name__!r}")
314-
self._raw_path = path
320+
self._raw_path = self._flavour.join(*paths)
315321

316322
@classmethod
317323
def _parse_path(cls, path):
@@ -615,7 +621,7 @@ def joinpath(self, *args):
615621
paths) or a totally different path (if one of the arguments is
616622
anchored).
617623
"""
618-
return self.__class__(self._raw_path, *args)
624+
return self.__class__(self, *args)
619625

620626
def __truediv__(self, key):
621627
try:
@@ -625,7 +631,7 @@ def __truediv__(self, key):
625631

626632
def __rtruediv__(self, key):
627633
try:
628-
return type(self)(key, self._raw_path)
634+
return type(self)(key, self)
629635
except TypeError:
630636
return NotImplemented
631637

@@ -859,7 +865,7 @@ def absolute(self):
859865
cwd = self._flavour.abspath(self.drive)
860866
else:
861867
cwd = os.getcwd()
862-
return type(self)(cwd, self._raw_path)
868+
return type(self)(cwd, self)
863869

864870
def resolve(self, strict=False):
865871
"""

Lib/test/test_pathlib.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ def test_bytes(self):
8181
r"where __fspath__ returns a str, not 'bytes'")
8282
with self.assertRaisesRegex(TypeError, message):
8383
P(b'a')
84-
with self.assertRaises(TypeError):
84+
with self.assertRaisesRegex(TypeError, message):
8585
P(b'a', 'b')
86-
with self.assertRaises(TypeError):
86+
with self.assertRaisesRegex(TypeError, message):
8787
P('a', b'b')
8888
with self.assertRaises(TypeError):
8989
P('a').joinpath(b'b')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix misleading exception message when mixed ``str`` and ``bytes`` arguments
2+
are supplied to :class:`pathlib.PurePath` and :class:`~pathlib.Path`.

0 commit comments

Comments
 (0)