Skip to content

Commit

Permalink
GH-103525: Improve exception message from pathlib.PurePath() (GH-10…
Browse files Browse the repository at this point in the history
…3526)

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.

Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
  • Loading branch information
barneygale and terryjreedy authored May 2, 2023
1 parent d81ca7e commit 8611e7b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 16 deletions.
37 changes: 23 additions & 14 deletions Lib/pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,18 +300,27 @@ def __reduce__(self):
return (self.__class__, self.parts)

def __init__(self, *args):
if not args:
path = ''
elif len(args) == 1:
path = os.fspath(args[0])
paths = []
for arg in args:
if isinstance(arg, PurePath):
path = arg._raw_path
else:
try:
path = os.fspath(arg)
except TypeError:
path = arg
if not isinstance(path, str):
raise TypeError(
"argument should be a str or an os.PathLike "
"object where __fspath__ returns a str, "
f"not {type(path).__name__!r}")
paths.append(path)
if len(paths) == 0:
self._raw_path = ''
elif len(paths) == 1:
self._raw_path = paths[0]
else:
path = self._flavour.join(*args)
if not isinstance(path, str):
raise TypeError(
"argument should be a str or an os.PathLike "
"object where __fspath__ returns a str, "
f"not {type(path).__name__!r}")
self._raw_path = path
self._raw_path = self._flavour.join(*paths)

@classmethod
def _parse_path(cls, path):
Expand Down Expand Up @@ -620,7 +629,7 @@ def joinpath(self, *args):
paths) or a totally different path (if one of the arguments is
anchored).
"""
return self.__class__(self._raw_path, *args)
return self.__class__(self, *args)

def __truediv__(self, key):
try:
Expand All @@ -630,7 +639,7 @@ def __truediv__(self, key):

def __rtruediv__(self, key):
try:
return type(self)(key, self._raw_path)
return type(self)(key, self)
except TypeError:
return NotImplemented

Expand Down Expand Up @@ -864,7 +873,7 @@ def absolute(self):
cwd = self._flavour.abspath(self.drive)
else:
cwd = os.getcwd()
return type(self)(cwd, self._raw_path)
return type(self)(cwd, self)

def resolve(self, strict=False):
"""
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ def test_bytes(self):
r"where __fspath__ returns a str, not 'bytes'")
with self.assertRaisesRegex(TypeError, message):
P(b'a')
with self.assertRaises(TypeError):
with self.assertRaisesRegex(TypeError, message):
P(b'a', 'b')
with self.assertRaises(TypeError):
with self.assertRaisesRegex(TypeError, message):
P('a', b'b')
with self.assertRaises(TypeError):
P('a').joinpath(b'b')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix misleading exception message when mixed ``str`` and ``bytes`` arguments
are supplied to :class:`pathlib.PurePath` and :class:`~pathlib.Path`.

0 comments on commit 8611e7b

Please sign in to comment.