GH-103525: Improve exception message from `pathlib.PurePath()` (GH-103526)

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>
This commit is contained in:
Barney Gale 2023-05-02 19:08:19 +01:00 committed by GitHub
parent d81ca7ec02
commit 8611e7bf5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 16 deletions

View File

@ -300,18 +300,27 @@ class PurePath(object):
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):
@ -620,7 +629,7 @@ class PurePath(object):
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:
@ -630,7 +639,7 @@ class PurePath(object):
def __rtruediv__(self, key):
try:
return type(self)(key, self._raw_path)
return type(self)(key, self)
except TypeError:
return NotImplemented
@ -864,7 +873,7 @@ class Path(PurePath):
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):
"""

View File

@ -81,9 +81,9 @@ class _BasePurePathTest(object):
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')

View File

@ -0,0 +1,2 @@
Fix misleading exception message when mixed ``str`` and ``bytes`` arguments
are supplied to :class:`pathlib.PurePath` and :class:`~pathlib.Path`.