Skip to content

Commit

Permalink
pythonGH-103525: Improve exception message from pathlib.PurePath()
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
barneygale committed Apr 13, 2023
1 parent a6f9594 commit 6c1131e
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 16 deletions.
34 changes: 20 additions & 14 deletions Lib/pathlib.py
Expand Up @@ -300,18 +300,24 @@ 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:
path = os.fspath(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 @@ -615,7 +621,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 @@ -625,7 +631,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 @@ -859,7 +865,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
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
@@ -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 6c1131e

Please sign in to comment.