mirror of https://github.com/python/cpython
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:
parent
d81ca7ec02
commit
8611e7bf5c
|
@ -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):
|
||||
"""
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Fix misleading exception message when mixed ``str`` and ``bytes`` arguments
|
||||
are supplied to :class:`pathlib.PurePath` and :class:`~pathlib.Path`.
|
Loading…
Reference in New Issue