From: Barney Gale Date: Tue, 2 May 2023 18:08:19 +0000 (+0100) Subject: GH-103525: Improve exception message from `pathlib.PurePath()` (GH-103526) X-Git-Tag: v3.12.0b1~323 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8611e7bf5ceace998fefcbf26ab1c5d5bc8a0e2a;p=thirdparty%2FPython%2Fcpython.git 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 --- diff --git a/Lib/pathlib.py b/Lib/pathlib.py index f43f01ef41a9..8eb08949fa9b 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -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): """ diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 76cfadeedcea..8b5b61a818bb 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -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') diff --git a/Misc/NEWS.d/next/Library/2023-04-13-19-43-15.gh-issue-103525.uY4VYg.rst b/Misc/NEWS.d/next/Library/2023-04-13-19-43-15.gh-issue-103525.uY4VYg.rst new file mode 100644 index 000000000000..1414cb07dd91 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-13-19-43-15.gh-issue-103525.uY4VYg.rst @@ -0,0 +1,2 @@ +Fix misleading exception message when mixed ``str`` and ``bytes`` arguments +are supplied to :class:`pathlib.PurePath` and :class:`~pathlib.Path`.