]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-89812: Clean up pathlib tests. (#104829)
authorBarney Gale <barney.gale@gmail.com>
Wed, 14 Jun 2023 04:06:58 +0000 (05:06 +0100)
committerGitHub <noreply@github.com>
Wed, 14 Jun 2023 04:06:58 +0000 (06:06 +0200)
Clean up pathlib tests.

Merge `PurePathTest` into `_BasePurePathTest`, and `PathTest` into
`_BasePathTest`.

Lib/test/test_pathlib.py

index 5963a3d67ff243f8ce00918703b54954acf3b80e..46ac30e91e32aab1badee104d4d43a060c93f183 100644 (file)
@@ -5,6 +5,7 @@ import sys
 import errno
 import pathlib
 import pickle
+import posixpath
 import socket
 import stat
 import tempfile
@@ -23,20 +24,23 @@ except ImportError:
     grp = pwd = None
 
 
-#
-# Tests for the pure classes.
-#
+# Make sure any symbolic links in the base test path are resolved.
+BASE = os.path.realpath(TESTFN)
+join = lambda *x: os.path.join(BASE, *x)
+rel_join = lambda *x: os.path.join(TESTFN, *x)
 
-class _BasePurePathSubclass(object):
-    def __init__(self, *pathsegments, session_id):
-        super().__init__(*pathsegments)
-        self.session_id = session_id
+only_nt = unittest.skipIf(os.name != 'nt',
+                          'test requires a Windows-compatible system')
+only_posix = unittest.skipIf(os.name == 'nt',
+                             'test requires a POSIX-compatible system')
 
-    def with_segments(self, *pathsegments):
-        return type(self)(*pathsegments, session_id=self.session_id)
 
+#
+# Tests for the pure classes.
+#
 
-class _BasePurePathTest(object):
+class PurePathTest(unittest.TestCase):
+    cls = pathlib.PurePath
 
     # Keys are canonical paths, values are list of tuples of arguments
     # supposed to produce equal paths.
@@ -75,6 +79,37 @@ class _BasePurePathTest(object):
         self.assertEqual(P(P('a'), P('b'), P('c')), P(FakePath("a/b/c")))
         self.assertEqual(P(P('./a:b')), P('./a:b'))
 
+    def test_concrete_class(self):
+        if self.cls is pathlib.PurePath:
+            expected = pathlib.PureWindowsPath if os.name == 'nt' else pathlib.PurePosixPath
+        else:
+            expected = self.cls
+        p = self.cls('a')
+        self.assertIs(type(p), expected)
+
+    def test_different_flavours_unequal(self):
+        p = self.cls('a')
+        if p._flavour is posixpath:
+            q = pathlib.PureWindowsPath('a')
+        else:
+            q = pathlib.PurePosixPath('a')
+        self.assertNotEqual(p, q)
+
+    def test_different_flavours_unordered(self):
+        p = self.cls('a')
+        if p._flavour is posixpath:
+            q = pathlib.PureWindowsPath('a')
+        else:
+            q = pathlib.PurePosixPath('a')
+        with self.assertRaises(TypeError):
+            p < q
+        with self.assertRaises(TypeError):
+            p <= q
+        with self.assertRaises(TypeError):
+            p > q
+        with self.assertRaises(TypeError):
+            p >= q
+
     def test_bytes(self):
         P = self.cls
         message = (r"argument should be a str or an os\.PathLike object "
@@ -122,8 +157,13 @@ class _BasePurePathTest(object):
         self._check_str_subclass('/a/b.txt')
 
     def test_with_segments_common(self):
-        class P(_BasePurePathSubclass, self.cls):
-            pass
+        class P(self.cls):
+            def __init__(self, *pathsegments, session_id):
+                super().__init__(*pathsegments)
+                self.session_id = session_id
+
+            def with_segments(self, *pathsegments):
+                return type(self)(*pathsegments, session_id=self.session_id)
         p = P('foo', 'bar', session_id=42)
         self.assertEqual(42, (p / 'foo').session_id)
         self.assertEqual(42, ('foo' / p).session_id)
@@ -723,7 +763,7 @@ class _BasePurePathTest(object):
             self.assertEqual(str(pp), str(p))
 
 
-class PurePosixPathTest(_BasePurePathTest, unittest.TestCase):
+class PurePosixPathTest(PurePathTest):
     cls = pathlib.PurePosixPath
 
     def test_drive_root_parts(self):
@@ -817,10 +857,10 @@ class PurePosixPathTest(_BasePurePathTest, unittest.TestCase):
         self.assertEqual(p, pp)
 
 
-class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase):
+class PureWindowsPathTest(PurePathTest):
     cls = pathlib.PureWindowsPath
 
-    equivalences = _BasePurePathTest.equivalences.copy()
+    equivalences = PurePathTest.equivalences.copy()
     equivalences.update({
         './a:b': [ ('./a:b',) ],
         'c:a': [ ('c:', 'a'), ('c:', 'a/'), ('.', 'c:', 'a') ],
@@ -1491,45 +1531,14 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase):
         self.assertIs(True, P('c:/baz/con/NUL').is_reserved())
         self.assertIs(False, P('c:/NUL/con/baz').is_reserved())
 
-class PurePathTest(_BasePurePathTest, unittest.TestCase):
-    cls = pathlib.PurePath
-
-    def test_concrete_class(self):
-        p = self.cls('a')
-        self.assertIs(type(p),
-            pathlib.PureWindowsPath if os.name == 'nt' else pathlib.PurePosixPath)
-
-    def test_different_flavours_unequal(self):
-        p = pathlib.PurePosixPath('a')
-        q = pathlib.PureWindowsPath('a')
-        self.assertNotEqual(p, q)
-
-    def test_different_flavours_unordered(self):
-        p = pathlib.PurePosixPath('a')
-        q = pathlib.PureWindowsPath('a')
-        with self.assertRaises(TypeError):
-            p < q
-        with self.assertRaises(TypeError):
-            p <= q
-        with self.assertRaises(TypeError):
-            p > q
-        with self.assertRaises(TypeError):
-            p >= q
-
 
-#
-# Tests for the concrete classes.
-#
+class PurePathSubclassTest(PurePathTest):
+    class cls(pathlib.PurePath):
+        pass
 
-# Make sure any symbolic links in the base test path are resolved.
-BASE = os.path.realpath(TESTFN)
-join = lambda *x: os.path.join(BASE, *x)
-rel_join = lambda *x: os.path.join(TESTFN, *x)
+    # repr() roundtripping is not supported in custom subclass.
+    test_repr_roundtrips = None
 
-only_nt = unittest.skipIf(os.name != 'nt',
-                          'test requires a Windows-compatible system')
-only_posix = unittest.skipIf(os.name == 'nt',
-                             'test requires a POSIX-compatible system')
 
 @only_posix
 class PosixPathAsPureTest(PurePosixPathTest):
@@ -1550,9 +1559,15 @@ class WindowsPathAsPureTest(PureWindowsPathTest):
             P('c:/').group()
 
 
-class _BasePathTest(object):
+#
+# Tests for the concrete classes.
+#
+
+class PathTest(unittest.TestCase):
     """Tests for the FS-accessing functionalities of the Path classes."""
 
+    cls = pathlib.Path
+
     # (BASE)
     #  |
     #  |-- brokenLink -> non-existing
@@ -1627,6 +1642,20 @@ class _BasePathTest(object):
     def assertEqualNormCase(self, path_a, path_b):
         self.assertEqual(os.path.normcase(path_a), os.path.normcase(path_b))
 
+    def test_concrete_class(self):
+        if self.cls is pathlib.Path:
+            expected = pathlib.WindowsPath if os.name == 'nt' else pathlib.PosixPath
+        else:
+            expected = self.cls
+        p = self.cls('a')
+        self.assertIs(type(p), expected)
+
+    def test_unsupported_flavour(self):
+        if self.cls._flavour is os.path:
+            self.skipTest("path flavour is supported")
+        else:
+            self.assertRaises(NotImplementedError, self.cls)
+
     def _test_cwd(self, p):
         q = self.cls(os.getcwd())
         self.assertEqual(p, q)
@@ -1683,8 +1712,13 @@ class _BasePathTest(object):
             self._test_home(self.cls.home())
 
     def test_with_segments(self):
-        class P(_BasePurePathSubclass, self.cls):
-            pass
+        class P(self.cls):
+            def __init__(self, *pathsegments, session_id):
+                super().__init__(*pathsegments)
+                self.session_id = session_id
+
+            def with_segments(self, *pathsegments):
+                return type(self)(*pathsegments, session_id=self.session_id)
         p = P(BASE, session_id=42)
         self.assertEqual(42, p.absolute().session_id)
         self.assertEqual(42, p.resolve().session_id)
@@ -1872,6 +1906,11 @@ class _BasePathTest(object):
         else:
             _check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE", "linkB"])
 
+    def test_glob_empty_pattern(self):
+        p = self.cls()
+        with self.assertRaisesRegex(ValueError, 'Unacceptable pattern'):
+            list(p.glob(''))
+
     def test_glob_case_sensitive(self):
         P = self.cls
         def _check(path, pattern, case_sensitive, expected):
@@ -3022,28 +3061,8 @@ class WalkTests(unittest.TestCase):
             list(base.walk(top_down=False))
 
 
-class PathTest(_BasePathTest, unittest.TestCase):
-    cls = pathlib.Path
-
-    def test_concrete_class(self):
-        p = self.cls('a')
-        self.assertIs(type(p),
-            pathlib.WindowsPath if os.name == 'nt' else pathlib.PosixPath)
-
-    def test_unsupported_flavour(self):
-        if os.name == 'nt':
-            self.assertRaises(NotImplementedError, pathlib.PosixPath)
-        else:
-            self.assertRaises(NotImplementedError, pathlib.WindowsPath)
-
-    def test_glob_empty_pattern(self):
-        p = self.cls()
-        with self.assertRaisesRegex(ValueError, 'Unacceptable pattern'):
-            list(p.glob(''))
-
-
 @only_posix
-class PosixPathTest(_BasePathTest, unittest.TestCase):
+class PosixPathTest(PathTest):
     cls = pathlib.PosixPath
 
     def test_absolute(self):
@@ -3227,7 +3246,7 @@ class PosixPathTest(_BasePathTest, unittest.TestCase):
 
 
 @only_nt
-class WindowsPathTest(_BasePathTest, unittest.TestCase):
+class WindowsPathTest(PathTest):
     cls = pathlib.WindowsPath
 
     def test_absolute(self):
@@ -3345,15 +3364,8 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase):
             check()
 
 
-class PurePathSubclassTest(_BasePurePathTest, unittest.TestCase):
-    class cls(pathlib.PurePath):
-        pass
-
-    # repr() roundtripping is not supported in custom subclass.
-    test_repr_roundtrips = None
-
 
-class PathSubclassTest(_BasePathTest, unittest.TestCase):
+class PathSubclassTest(PathTest):
     class cls(pathlib.Path):
         pass