]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-112675: Move path joining tests into `test_posixpath` and `test_ntpath` (#112676)
authorBarney Gale <barney.gale@gmail.com>
Thu, 7 Dec 2023 21:45:40 +0000 (21:45 +0000)
committerGitHub <noreply@github.com>
Thu, 7 Dec 2023 21:45:40 +0000 (21:45 +0000)
In `test_pathlib`, the `check_drive_root_parts` test methods evaluated
both joining and parsing/normalisation of paths. This dates from a time
when pathlib implemented both functions itself, but nowadays path joining
is done with `posixpath.join()` and `ntpath.join()`.

This commit moves the joining-related test cases into `test_posixpath` and
`test_ntpath`.

Lib/test/test_ntpath.py
Lib/test/test_pathlib.py
Lib/test/test_posixpath.py

index 3e710d1c6dabe450625ebfd564854340c0bf14f5..bf990ed36fbcae0791a665d34e8e7f4fefe1a5ca 100644 (file)
@@ -256,6 +256,7 @@ class TestNtpath(NtpathTestCase):
         tester('ntpath.join("a", "b", "c")', 'a\\b\\c')
         tester('ntpath.join("a\\", "b", "c")', 'a\\b\\c')
         tester('ntpath.join("a", "b\\", "c")', 'a\\b\\c')
+        tester('ntpath.join("a", "b", "c\\")', 'a\\b\\c\\')
         tester('ntpath.join("a", "b", "\\c")', '\\c')
         tester('ntpath.join("d:\\", "\\pleep")', 'd:\\pleep')
         tester('ntpath.join("d:\\", "a", "b")', 'd:\\a\\b')
@@ -313,6 +314,16 @@ class TestNtpath(NtpathTestCase):
         tester("ntpath.join('\\\\computer\\', 'share')", '\\\\computer\\share')
         tester("ntpath.join('\\\\computer\\share\\', 'a')", '\\\\computer\\share\\a')
         tester("ntpath.join('\\\\computer\\share\\a\\', 'b')", '\\\\computer\\share\\a\\b')
+        # Second part is anchored, so that the first part is ignored.
+        tester("ntpath.join('a', 'Z:b', 'c')", 'Z:b\\c')
+        tester("ntpath.join('a', 'Z:\\b', 'c')", 'Z:\\b\\c')
+        tester("ntpath.join('a', '\\\\b\\c', 'd')", '\\\\b\\c\\d')
+        # Second part has a root but not drive.
+        tester("ntpath.join('a', '\\b', 'c')", '\\b\\c')
+        tester("ntpath.join('Z:/a', '/b', 'c')", 'Z:\\b\\c')
+        tester("ntpath.join('//?/Z:/a', '/b', 'c')",  '\\\\?\\Z:\\b\\c')
+        tester("ntpath.join('D:a', './c:b')", 'D:a\\.\\c:b')
+        tester("ntpath.join('D:/a', './c:b')", 'D:\\a\\.\\c:b')
 
     def test_normpath(self):
         tester("ntpath.normpath('A//////././//.//B')", r'A\B')
index 1b10d6c2f0cb19034e62fbc4b0fe32d551df9df3..ea922143e36e4853c4fa714cf7760f767de0c3e2 100644 (file)
@@ -160,45 +160,30 @@ class PurePathTest(unittest.TestCase):
         for parent in p.parents:
             self.assertEqual(42, parent.session_id)
 
-    def _get_drive_root_parts(self, parts):
-        path = self.cls(*parts)
-        return path.drive, path.root, path.parts
-
-    def _check_drive_root_parts(self, arg, *expected):
+    def _check_parse_path(self, raw_path, *expected):
         sep = self.pathmod.sep
-        actual = self._get_drive_root_parts([x.replace('/', sep) for x in arg])
+        actual = self.cls._parse_path(raw_path.replace('/', sep))
         self.assertEqual(actual, expected)
         if altsep := self.pathmod.altsep:
-            actual = self._get_drive_root_parts([x.replace('/', altsep) for x in arg])
+            actual = self.cls._parse_path(raw_path.replace('/', altsep))
             self.assertEqual(actual, expected)
 
-    def test_drive_root_parts_common(self):
-        check = self._check_drive_root_parts
+    def test_parse_path_common(self):
+        check = self._check_parse_path
         sep = self.pathmod.sep
-        # Unanchored parts.
-        check((),                   '', '', ())
-        check(('a',),               '', '', ('a',))
-        check(('a/',),              '', '', ('a',))
-        check(('a', 'b'),           '', '', ('a', 'b'))
-        # Expansion.
-        check(('a/b',),             '', '', ('a', 'b'))
-        check(('a/b/',),            '', '', ('a', 'b'))
-        check(('a', 'b/c', 'd'),    '', '', ('a', 'b', 'c', 'd'))
-        # Collapsing and stripping excess slashes.
-        check(('a', 'b//c', 'd'),   '', '', ('a', 'b', 'c', 'd'))
-        check(('a', 'b/c/', 'd'),   '', '', ('a', 'b', 'c', 'd'))
-        # Eliminating standalone dots.
-        check(('.',),               '', '', ())
-        check(('.', '.', 'b'),      '', '', ('b',))
-        check(('a', '.', 'b'),      '', '', ('a', 'b'))
-        check(('a', '.', '.'),      '', '', ('a',))
-        # The first part is anchored.
-        check(('/a/b',),            '', sep, (sep, 'a', 'b'))
-        check(('/a', 'b'),          '', sep, (sep, 'a', 'b'))
-        check(('/a/', 'b'),         '', sep, (sep, 'a', 'b'))
-        # Ignoring parts before an anchored part.
-        check(('a', '/b', 'c'),     '', sep, (sep, 'b', 'c'))
-        check(('a', '/b', '/c'),    '', sep, (sep, 'c'))
+        check('',         '', '', [])
+        check('a',        '', '', ['a'])
+        check('a/',       '', '', ['a'])
+        check('a/b',      '', '', ['a', 'b'])
+        check('a/b/',     '', '', ['a', 'b'])
+        check('a/b/c/d',  '', '', ['a', 'b', 'c', 'd'])
+        check('a/b//c/d', '', '', ['a', 'b', 'c', 'd'])
+        check('a/b/c/d',  '', '', ['a', 'b', 'c', 'd'])
+        check('.',        '', '', [])
+        check('././b',    '', '', ['b'])
+        check('a/./b',    '', '', ['a', 'b'])
+        check('a/./.',    '', '', ['a'])
+        check('/a/b',     '', sep, ['a', 'b'])
 
     def test_join_common(self):
         P = self.cls
@@ -792,17 +777,17 @@ class PurePathTest(unittest.TestCase):
 class PurePosixPathTest(PurePathTest):
     cls = pathlib.PurePosixPath
 
-    def test_drive_root_parts(self):
-        check = self._check_drive_root_parts
+    def test_parse_path(self):
+        check = self._check_parse_path
         # Collapsing of excess leading slashes, except for the double-slash
         # special case.
-        check(('//a', 'b'),             '', '//', ('//', 'a', 'b'))
-        check(('///a', 'b'),            '', '/', ('/', 'a', 'b'))
-        check(('////a', 'b'),           '', '/', ('/', 'a', 'b'))
+        check('//a/b',   '', '//', ['a', 'b'])
+        check('///a/b',  '', '/', ['a', 'b'])
+        check('////a/b', '', '/', ['a', 'b'])
         # Paths which look like NT paths aren't treated specially.
-        check(('c:a',),                 '', '', ('c:a',))
-        check(('c:\\a',),               '', '', ('c:\\a',))
-        check(('\\a',),                 '', '', ('\\a',))
+        check('c:a',     '', '', ['c:a',])
+        check('c:\\a',   '', '', ['c:\\a',])
+        check('\\a',     '', '', ['\\a',])
 
     def test_root(self):
         P = self.cls
@@ -900,67 +885,53 @@ class PureWindowsPathTest(PurePathTest):
             ],
     })
 
-    def test_drive_root_parts(self):
-        check = self._check_drive_root_parts
+    def test_parse_path(self):
+        check = self._check_parse_path
         # First part is anchored.
-        check(('c:',),                  'c:', '', ('c:',))
-        check(('c:/',),                 'c:', '\\', ('c:\\',))
-        check(('/',),                   '', '\\', ('\\',))
-        check(('c:a',),                 'c:', '', ('c:', 'a'))
-        check(('c:/a',),                'c:', '\\', ('c:\\', 'a'))
-        check(('/a',),                  '', '\\', ('\\', 'a'))
-        # UNC paths.
-        check(('//',),                  '\\\\', '', ('\\\\',))
-        check(('//a',),                 '\\\\a', '', ('\\\\a',))
-        check(('//a/',),                '\\\\a\\', '', ('\\\\a\\',))
-        check(('//a/b',),               '\\\\a\\b', '\\', ('\\\\a\\b\\',))
-        check(('//a/b/',),              '\\\\a\\b', '\\', ('\\\\a\\b\\',))
-        check(('//a/b/c',),             '\\\\a\\b', '\\', ('\\\\a\\b\\', 'c'))
-        # Second part is anchored, so that the first part is ignored.
-        check(('a', 'Z:b', 'c'),        'Z:', '', ('Z:', 'b', 'c'))
-        check(('a', 'Z:/b', 'c'),       'Z:', '\\', ('Z:\\', 'b', 'c'))
+        check('c:',                  'c:', '', [])
+        check('c:/',                 'c:', '\\', [])
+        check('/',                   '', '\\', [])
+        check('c:a',                 'c:', '', ['a'])
+        check('c:/a',                'c:', '\\', ['a'])
+        check('/a',                  '', '\\', ['a'])
         # UNC paths.
-        check(('a', '//b/c', 'd'),      '\\\\b\\c', '\\', ('\\\\b\\c\\', 'd'))
+        check('//',                  '\\\\', '', [])
+        check('//a',                 '\\\\a', '', [])
+        check('//a/',                '\\\\a\\', '', [])
+        check('//a/b',               '\\\\a\\b', '\\', [])
+        check('//a/b/',              '\\\\a\\b', '\\', [])
+        check('//a/b/c',             '\\\\a\\b', '\\', ['c'])
         # Collapsing and stripping excess slashes.
-        check(('a', 'Z://b//c/', 'd/'), 'Z:', '\\', ('Z:\\', 'b', 'c', 'd'))
+        check('Z://b//c/d/',         'Z:', '\\', ['b', 'c', 'd'])
         # UNC paths.
-        check(('a', '//b/c//', 'd'),    '\\\\b\\c', '\\', ('\\\\b\\c\\', 'd'))
+        check('//b/c//d',            '\\\\b\\c', '\\', ['d'])
         # Extended paths.
-        check(('//./c:',),              '\\\\.\\c:', '', ('\\\\.\\c:',))
-        check(('//?/c:/',),             '\\\\?\\c:', '\\', ('\\\\?\\c:\\',))
-        check(('//?/c:/a',),            '\\\\?\\c:', '\\', ('\\\\?\\c:\\', 'a'))
-        check(('//?/c:/a', '/b'),       '\\\\?\\c:', '\\', ('\\\\?\\c:\\', 'b'))
+        check('//./c:',              '\\\\.\\c:', '', [])
+        check('//?/c:/',             '\\\\?\\c:', '\\', [])
+        check('//?/c:/a',            '\\\\?\\c:', '\\', ['a'])
         # Extended UNC paths (format is "\\?\UNC\server\share").
-        check(('//?',),                 '\\\\?', '', ('\\\\?',))
-        check(('//?/',),                '\\\\?\\', '', ('\\\\?\\',))
-        check(('//?/UNC',),             '\\\\?\\UNC', '', ('\\\\?\\UNC',))
-        check(('//?/UNC/',),            '\\\\?\\UNC\\', '', ('\\\\?\\UNC\\',))
-        check(('//?/UNC/b',),           '\\\\?\\UNC\\b', '', ('\\\\?\\UNC\\b',))
-        check(('//?/UNC/b/',),          '\\\\?\\UNC\\b\\', '', ('\\\\?\\UNC\\b\\',))
-        check(('//?/UNC/b/c',),         '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\',))
-        check(('//?/UNC/b/c/',),        '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\',))
-        check(('//?/UNC/b/c/d',),       '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\', 'd'))
+        check('//?',                 '\\\\?', '', [])
+        check('//?/',                '\\\\?\\', '', [])
+        check('//?/UNC',             '\\\\?\\UNC', '', [])
+        check('//?/UNC/',            '\\\\?\\UNC\\', '', [])
+        check('//?/UNC/b',           '\\\\?\\UNC\\b', '', [])
+        check('//?/UNC/b/',          '\\\\?\\UNC\\b\\', '', [])
+        check('//?/UNC/b/c',         '\\\\?\\UNC\\b\\c', '\\', [])
+        check('//?/UNC/b/c/',        '\\\\?\\UNC\\b\\c', '\\', [])
+        check('//?/UNC/b/c/d',       '\\\\?\\UNC\\b\\c', '\\', ['d'])
         # UNC device paths
-        check(('//./BootPartition/',),   '\\\\.\\BootPartition', '\\', ('\\\\.\\BootPartition\\',))
-        check(('//?/BootPartition/',),   '\\\\?\\BootPartition', '\\', ('\\\\?\\BootPartition\\',))
-        check(('//./PhysicalDrive0',),   '\\\\.\\PhysicalDrive0', '', ('\\\\.\\PhysicalDrive0',))
-        check(('//?/Volume{}/',),        '\\\\?\\Volume{}', '\\', ('\\\\?\\Volume{}\\',))
-        check(('//./nul',),              '\\\\.\\nul', '', ('\\\\.\\nul',))
-        # Second part has a root but not drive.
-        check(('a', '/b', 'c'),         '', '\\', ('\\', 'b', 'c'))
-        check(('Z:/a', '/b', 'c'),      'Z:', '\\', ('Z:\\', 'b', 'c'))
-        check(('//?/Z:/a', '/b', 'c'),  '\\\\?\\Z:', '\\', ('\\\\?\\Z:\\', 'b', 'c'))
-        # Joining with the same drive => the first path is appended to if
-        # the second path is relative.
-        check(('c:/a/b', 'c:x/y'),      'c:', '\\', ('c:\\', 'a', 'b', 'x', 'y'))
-        check(('c:/a/b', 'c:/x/y'),     'c:', '\\', ('c:\\', 'x', 'y'))
+        check('//./BootPartition/',  '\\\\.\\BootPartition', '\\', [])
+        check('//?/BootPartition/',  '\\\\?\\BootPartition', '\\', [])
+        check('//./PhysicalDrive0',  '\\\\.\\PhysicalDrive0', '', [])
+        check('//?/Volume{}/',       '\\\\?\\Volume{}', '\\', [])
+        check('//./nul',             '\\\\.\\nul', '', [])
         # Paths to files with NTFS alternate data streams
-        check(('./c:s',),               '', '', ('c:s',))
-        check(('cc:s',),                '', '', ('cc:s',))
-        check(('C:c:s',),               'C:', '', ('C:', 'c:s'))
-        check(('C:/c:s',),              'C:', '\\', ('C:\\', 'c:s'))
-        check(('D:a', './c:b'),         'D:', '', ('D:', 'a', 'c:b'))
-        check(('D:/a', './c:b'),        'D:', '\\', ('D:\\', 'a', 'c:b'))
+        check('./c:s',               '', '', ['c:s'])
+        check('cc:s',                '', '', ['cc:s'])
+        check('C:c:s',               'C:', '', ['c:s'])
+        check('C:/c:s',              'C:', '\\', ['c:s'])
+        check('D:a/c:b',             'D:', '', ['a', 'c:b'])
+        check('D:/a/c:b',            'D:', '\\', ['a', 'c:b'])
 
     def test_str(self):
         p = self.cls('a/b/c')
index 9be4640f970aeffc37d0e02b638cbadcfd448dd9..86ce1b1d41ba61ac2916672df879d58abffc9c45 100644 (file)
@@ -47,18 +47,26 @@ class PosixPathTest(unittest.TestCase):
             safe_rmdir(os_helper.TESTFN + suffix)
 
     def test_join(self):
-        self.assertEqual(posixpath.join("/foo", "bar", "/bar", "baz"),
-                         "/bar/baz")
-        self.assertEqual(posixpath.join("/foo", "bar", "baz"), "/foo/bar/baz")
-        self.assertEqual(posixpath.join("/foo/", "bar/", "baz/"),
-                         "/foo/bar/baz/")
-
-        self.assertEqual(posixpath.join(b"/foo", b"bar", b"/bar", b"baz"),
-                         b"/bar/baz")
-        self.assertEqual(posixpath.join(b"/foo", b"bar", b"baz"),
-                         b"/foo/bar/baz")
-        self.assertEqual(posixpath.join(b"/foo/", b"bar/", b"baz/"),
-                         b"/foo/bar/baz/")
+        fn = posixpath.join
+        self.assertEqual(fn("/foo", "bar", "/bar", "baz"), "/bar/baz")
+        self.assertEqual(fn("/foo", "bar", "baz"),         "/foo/bar/baz")
+        self.assertEqual(fn("/foo/", "bar/", "baz/"),      "/foo/bar/baz/")
+
+        self.assertEqual(fn(b"/foo", b"bar", b"/bar", b"baz"), b"/bar/baz")
+        self.assertEqual(fn(b"/foo", b"bar", b"baz"),          b"/foo/bar/baz")
+        self.assertEqual(fn(b"/foo/", b"bar/", b"baz/"),       b"/foo/bar/baz/")
+
+        self.assertEqual(fn("a", "b"),         "a/b")
+        self.assertEqual(fn("a", "b/"),        "a/b/")
+        self.assertEqual(fn("a/", "b"),        "a/b")
+        self.assertEqual(fn("a/", "b/"),       "a/b/")
+        self.assertEqual(fn("a", "b/c", "d"),  "a/b/c/d")
+        self.assertEqual(fn("a", "b//c", "d"), "a/b//c/d")
+        self.assertEqual(fn("a", "b/c/", "d"), "a/b/c/d")
+        self.assertEqual(fn("/a", "b"),        "/a/b")
+        self.assertEqual(fn("/a/", "b"),       "/a/b")
+        self.assertEqual(fn("a", "/b", "c"),   "/b/c")
+        self.assertEqual(fn("a", "/b", "/c"),  "/c")
 
     def test_split(self):
         self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar"))