]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
pathlib ABCs: drop partial, broken, untested support for `bytes` paths. (#114777)
authorBarney Gale <barney.gale@gmail.com>
Wed, 31 Jan 2024 00:59:33 +0000 (00:59 +0000)
committerGitHub <noreply@github.com>
Wed, 31 Jan 2024 00:59:33 +0000 (00:59 +0000)
Methods like `full_match()`, `glob()`, etc, are difficult to make work with
byte paths, and it's not worth the effort. This patch makes `PurePathBase`
raise `TypeError` when given non-`str` path segments.

Lib/pathlib/_abc.py
Lib/test/test_pathlib/test_pathlib.py
Lib/test/test_pathlib/test_pathlib_abc.py

index 85884bc4b4cb47bd1a7353027bcfe13c7165cb69..91f5cd6c01e9d088cf8c11c171a742c31f9d2580 100644 (file)
@@ -207,6 +207,9 @@ class PurePathBase:
 
     def __init__(self, path, *paths):
         self._raw_path = self.pathmod.join(path, *paths) if paths else path
+        if not isinstance(self._raw_path, str):
+            raise TypeError(
+                f"path should be a str, not {type(self._raw_path).__name__!r}")
         self._resolving = False
 
     def with_segments(self, *pathsegments):
@@ -321,8 +324,6 @@ class PurePathBase:
             other = self.with_segments(other)
         anchor0, parts0 = self._stack
         anchor1, parts1 = other._stack
-        if isinstance(anchor0, str) != isinstance(anchor1, str):
-            raise TypeError(f"{self._raw_path!r} and {other._raw_path!r} have different types")
         if anchor0 != anchor1:
             raise ValueError(f"{self._raw_path!r} and {other._raw_path!r} have different anchors")
         while parts0 and parts1 and parts0[-1] == parts1[-1]:
@@ -346,8 +347,6 @@ class PurePathBase:
             other = self.with_segments(other)
         anchor0, parts0 = self._stack
         anchor1, parts1 = other._stack
-        if isinstance(anchor0, str) != isinstance(anchor1, str):
-            raise TypeError(f"{self._raw_path!r} and {other._raw_path!r} have different types")
         if anchor0 != anchor1:
             return False
         while parts0 and parts1 and parts0[-1] == parts1[-1]:
index 3bee9b8c762b805a6ca4f9901ffc720415bbcc54..2b166451243775b83a4850bcba96144cd923a8c1 100644 (file)
@@ -189,7 +189,7 @@ class PurePathTest(test_pathlib_abc.DummyPurePathTest):
         self._check_str(p.__fspath__(), ('a/b',))
         self._check_str(os.fspath(p), ('a/b',))
 
-    def test_bytes(self):
+    def test_bytes_exc_message(self):
         P = self.cls
         message = (r"argument should be a str or an os\.PathLike object "
                    r"where __fspath__ returns a str, not 'bytes'")
@@ -199,22 +199,6 @@ class PurePathTest(test_pathlib_abc.DummyPurePathTest):
             P(b'a', 'b')
         with self.assertRaisesRegex(TypeError, message):
             P('a', b'b')
-        with self.assertRaises(TypeError):
-            P('a').joinpath(b'b')
-        with self.assertRaises(TypeError):
-            P('a') / b'b'
-        with self.assertRaises(TypeError):
-            b'a' / P('b')
-        with self.assertRaises(TypeError):
-            P('a').match(b'b')
-        with self.assertRaises(TypeError):
-            P('a').relative_to(b'b')
-        with self.assertRaises(TypeError):
-            P('a').with_name(b'b')
-        with self.assertRaises(TypeError):
-            P('a').with_stem(b'b')
-        with self.assertRaises(TypeError):
-            P('a').with_suffix(b'b')
 
     def test_as_bytes_common(self):
         sep = os.fsencode(self.sep)
index 0e12182c162c14218ea77e11c4b234641e59fee8..207579ccbf443b78cdec48094037c2463f754abc 100644 (file)
@@ -155,6 +155,31 @@ class DummyPurePathTest(unittest.TestCase):
         P('a/b/c')
         P('/a/b/c')
 
+    def test_bytes(self):
+        P = self.cls
+        with self.assertRaises(TypeError):
+            P(b'a')
+        with self.assertRaises(TypeError):
+            P(b'a', 'b')
+        with self.assertRaises(TypeError):
+            P('a', b'b')
+        with self.assertRaises(TypeError):
+            P('a').joinpath(b'b')
+        with self.assertRaises(TypeError):
+            P('a') / b'b'
+        with self.assertRaises(TypeError):
+            b'a' / P('b')
+        with self.assertRaises(TypeError):
+            P('a').match(b'b')
+        with self.assertRaises(TypeError):
+            P('a').relative_to(b'b')
+        with self.assertRaises(TypeError):
+            P('a').with_name(b'b')
+        with self.assertRaises(TypeError):
+            P('a').with_stem(b'b')
+        with self.assertRaises(TypeError):
+            P('a').with_suffix(b'b')
+
     def _check_str_subclass(self, *args):
         # Issue #21127: it should be possible to construct a PurePath object
         # from a str subclass instance, and it then gets converted to