|
24 | 24 | grp = pwd = None
|
25 | 25 |
|
26 | 26 |
|
27 |
| -class _BaseFlavourTest(object): |
28 |
| - |
29 |
| - def _check_parse_parts(self, arg, expected): |
30 |
| - def f(parts): |
31 |
| - path = self.cls(*parts)._raw_path |
32 |
| - return self.cls._parse_path(path) |
33 |
| - sep = self.flavour.sep |
34 |
| - altsep = self.flavour.altsep |
35 |
| - actual = f([x.replace('/', sep) for x in arg]) |
36 |
| - self.assertEqual(actual, expected) |
37 |
| - if altsep: |
38 |
| - actual = f([x.replace('/', altsep) for x in arg]) |
39 |
| - self.assertEqual(actual, expected) |
40 |
| - |
41 |
| - def test_parse_parts_common(self): |
42 |
| - check = self._check_parse_parts |
43 |
| - sep = self.flavour.sep |
44 |
| - # Unanchored parts. |
45 |
| - check([], ('', '', [])) |
46 |
| - check(['a'], ('', '', ['a'])) |
47 |
| - check(['a/'], ('', '', ['a'])) |
48 |
| - check(['a', 'b'], ('', '', ['a', 'b'])) |
49 |
| - # Expansion. |
50 |
| - check(['a/b'], ('', '', ['a', 'b'])) |
51 |
| - check(['a/b/'], ('', '', ['a', 'b'])) |
52 |
| - check(['a', 'b/c', 'd'], ('', '', ['a', 'b', 'c', 'd'])) |
53 |
| - # Collapsing and stripping excess slashes. |
54 |
| - check(['a', 'b//c', 'd'], ('', '', ['a', 'b', 'c', 'd'])) |
55 |
| - check(['a', 'b/c/', 'd'], ('', '', ['a', 'b', 'c', 'd'])) |
56 |
| - # Eliminating standalone dots. |
57 |
| - check(['.'], ('', '', [])) |
58 |
| - check(['.', '.', 'b'], ('', '', ['b'])) |
59 |
| - check(['a', '.', 'b'], ('', '', ['a', 'b'])) |
60 |
| - check(['a', '.', '.'], ('', '', ['a'])) |
61 |
| - # The first part is anchored. |
62 |
| - check(['/a/b'], ('', sep, [sep, 'a', 'b'])) |
63 |
| - check(['/a', 'b'], ('', sep, [sep, 'a', 'b'])) |
64 |
| - check(['/a/', 'b'], ('', sep, [sep, 'a', 'b'])) |
65 |
| - # Ignoring parts before an anchored part. |
66 |
| - check(['a', '/b', 'c'], ('', sep, [sep, 'b', 'c'])) |
67 |
| - check(['a', '/b', '/c'], ('', sep, [sep, 'c'])) |
68 |
| - |
69 |
| - |
70 |
| -class PosixFlavourTest(_BaseFlavourTest, unittest.TestCase): |
71 |
| - cls = pathlib.PurePosixPath |
72 |
| - flavour = pathlib.PurePosixPath._flavour |
73 |
| - |
74 |
| - def test_parse_parts(self): |
75 |
| - check = self._check_parse_parts |
76 |
| - # Collapsing of excess leading slashes, except for the double-slash |
77 |
| - # special case. |
78 |
| - check(['//a', 'b'], ('', '//', ['//', 'a', 'b'])) |
79 |
| - check(['///a', 'b'], ('', '/', ['/', 'a', 'b'])) |
80 |
| - check(['////a', 'b'], ('', '/', ['/', 'a', 'b'])) |
81 |
| - # Paths which look like NT paths aren't treated specially. |
82 |
| - check(['c:a'], ('', '', ['c:a'])) |
83 |
| - check(['c:\\a'], ('', '', ['c:\\a'])) |
84 |
| - check(['\\a'], ('', '', ['\\a'])) |
85 |
| - |
86 |
| - |
87 |
| -class NTFlavourTest(_BaseFlavourTest, unittest.TestCase): |
88 |
| - cls = pathlib.PureWindowsPath |
89 |
| - flavour = pathlib.PureWindowsPath._flavour |
90 |
| - |
91 |
| - def test_parse_parts(self): |
92 |
| - check = self._check_parse_parts |
93 |
| - # First part is anchored. |
94 |
| - check(['c:'], ('c:', '', ['c:'])) |
95 |
| - check(['c:/'], ('c:', '\\', ['c:\\'])) |
96 |
| - check(['/'], ('', '\\', ['\\'])) |
97 |
| - check(['c:a'], ('c:', '', ['c:', 'a'])) |
98 |
| - check(['c:/a'], ('c:', '\\', ['c:\\', 'a'])) |
99 |
| - check(['/a'], ('', '\\', ['\\', 'a'])) |
100 |
| - # UNC paths. |
101 |
| - check(['//a/b'], ('\\\\a\\b', '\\', ['\\\\a\\b\\'])) |
102 |
| - check(['//a/b/'], ('\\\\a\\b', '\\', ['\\\\a\\b\\'])) |
103 |
| - check(['//a/b/c'], ('\\\\a\\b', '\\', ['\\\\a\\b\\', 'c'])) |
104 |
| - # Second part is anchored, so that the first part is ignored. |
105 |
| - check(['a', 'Z:b', 'c'], ('Z:', '', ['Z:', 'b', 'c'])) |
106 |
| - check(['a', 'Z:/b', 'c'], ('Z:', '\\', ['Z:\\', 'b', 'c'])) |
107 |
| - # UNC paths. |
108 |
| - check(['a', '//b/c', 'd'], ('\\\\b\\c', '\\', ['\\\\b\\c\\', 'd'])) |
109 |
| - # Collapsing and stripping excess slashes. |
110 |
| - check(['a', 'Z://b//c/', 'd/'], ('Z:', '\\', ['Z:\\', 'b', 'c', 'd'])) |
111 |
| - # UNC paths. |
112 |
| - check(['a', '//b/c//', 'd'], ('\\\\b\\c', '\\', ['\\\\b\\c\\', 'd'])) |
113 |
| - # Extended paths. |
114 |
| - check(['//?/c:/'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\'])) |
115 |
| - check(['//?/c:/a'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\', 'a'])) |
116 |
| - check(['//?/c:/a', '/b'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\', 'b'])) |
117 |
| - # Extended UNC paths (format is "\\?\UNC\server\share"). |
118 |
| - check(['//?/UNC/b/c'], ('\\\\?\\UNC\\b\\c', '\\', ['\\\\?\\UNC\\b\\c\\'])) |
119 |
| - check(['//?/UNC/b/c/d'], ('\\\\?\\UNC\\b\\c', '\\', ['\\\\?\\UNC\\b\\c\\', 'd'])) |
120 |
| - # Second part has a root but not drive. |
121 |
| - check(['a', '/b', 'c'], ('', '\\', ['\\', 'b', 'c'])) |
122 |
| - check(['Z:/a', '/b', 'c'], ('Z:', '\\', ['Z:\\', 'b', 'c'])) |
123 |
| - check(['//?/Z:/a', '/b', 'c'], ('\\\\?\\Z:', '\\', ['\\\\?\\Z:\\', 'b', 'c'])) |
124 |
| - # Joining with the same drive => the first path is appended to if |
125 |
| - # the second path is relative. |
126 |
| - check(['c:/a/b', 'c:x/y'], ('c:', '\\', ['c:\\', 'a', 'b', 'x', 'y'])) |
127 |
| - check(['c:/a/b', 'c:/x/y'], ('c:', '\\', ['c:\\', 'x', 'y'])) |
128 |
| - # Paths to files with NTFS alternate data streams |
129 |
| - check(['./c:s'], ('', '', ['c:s'])) |
130 |
| - check(['cc:s'], ('', '', ['cc:s'])) |
131 |
| - check(['C:c:s'], ('C:', '', ['C:', 'c:s'])) |
132 |
| - check(['C:/c:s'], ('C:', '\\', ['C:\\', 'c:s'])) |
133 |
| - check(['D:a', './c:b'], ('D:', '', ['D:', 'a', 'c:b'])) |
134 |
| - check(['D:/a', './c:b'], ('D:', '\\', ['D:\\', 'a', 'c:b'])) |
135 |
| - |
136 |
| - |
137 | 27 | #
|
138 | 28 | # Tests for the pure classes.
|
139 | 29 | #
|
@@ -246,6 +136,46 @@ class P(_BasePurePathSubclass, self.cls):
|
246 | 136 | for parent in p.parents:
|
247 | 137 | self.assertTrue(parent.init_called)
|
248 | 138 |
|
| 139 | + def _get_drive_root_parts(self, parts): |
| 140 | + path = self.cls(*parts) |
| 141 | + return path.drive, path.root, path.parts |
| 142 | + |
| 143 | + def _check_drive_root_parts(self, arg, *expected): |
| 144 | + sep = self.flavour.sep |
| 145 | + actual = self._get_drive_root_parts([x.replace('/', sep) for x in arg]) |
| 146 | + self.assertEqual(actual, expected) |
| 147 | + if altsep := self.flavour.altsep: |
| 148 | + actual = self._get_drive_root_parts([x.replace('/', altsep) for x in arg]) |
| 149 | + self.assertEqual(actual, expected) |
| 150 | + |
| 151 | + def test_drive_root_parts_common(self): |
| 152 | + check = self._check_drive_root_parts |
| 153 | + sep = self.flavour.sep |
| 154 | + # Unanchored parts. |
| 155 | + check((), '', '', ()) |
| 156 | + check(('a',), '', '', ('a',)) |
| 157 | + check(('a/',), '', '', ('a',)) |
| 158 | + check(('a', 'b'), '', '', ('a', 'b')) |
| 159 | + # Expansion. |
| 160 | + check(('a/b',), '', '', ('a', 'b')) |
| 161 | + check(('a/b/',), '', '', ('a', 'b')) |
| 162 | + check(('a', 'b/c', 'd'), '', '', ('a', 'b', 'c', 'd')) |
| 163 | + # Collapsing and stripping excess slashes. |
| 164 | + check(('a', 'b//c', 'd'), '', '', ('a', 'b', 'c', 'd')) |
| 165 | + check(('a', 'b/c/', 'd'), '', '', ('a', 'b', 'c', 'd')) |
| 166 | + # Eliminating standalone dots. |
| 167 | + check(('.',), '', '', ()) |
| 168 | + check(('.', '.', 'b'), '', '', ('b',)) |
| 169 | + check(('a', '.', 'b'), '', '', ('a', 'b')) |
| 170 | + check(('a', '.', '.'), '', '', ('a',)) |
| 171 | + # The first part is anchored. |
| 172 | + check(('/a/b',), '', sep, (sep, 'a', 'b')) |
| 173 | + check(('/a', 'b'), '', sep, (sep, 'a', 'b')) |
| 174 | + check(('/a/', 'b'), '', sep, (sep, 'a', 'b')) |
| 175 | + # Ignoring parts before an anchored part. |
| 176 | + check(('a', '/b', 'c'), '', sep, (sep, 'b', 'c')) |
| 177 | + check(('a', '/b', '/c'), '', sep, (sep, 'c')) |
| 178 | + |
249 | 179 | def test_join_common(self):
|
250 | 180 | P = self.cls
|
251 | 181 | p = P('a/b')
|
@@ -770,6 +700,18 @@ def test_pickling_common(self):
|
770 | 700 | class PurePosixPathTest(_BasePurePathTest, unittest.TestCase):
|
771 | 701 | cls = pathlib.PurePosixPath
|
772 | 702 |
|
| 703 | + def test_drive_root_parts(self): |
| 704 | + check = self._check_drive_root_parts |
| 705 | + # Collapsing of excess leading slashes, except for the double-slash |
| 706 | + # special case. |
| 707 | + check(('//a', 'b'), '', '//', ('//', 'a', 'b')) |
| 708 | + check(('///a', 'b'), '', '/', ('/', 'a', 'b')) |
| 709 | + check(('////a', 'b'), '', '/', ('/', 'a', 'b')) |
| 710 | + # Paths which look like NT paths aren't treated specially. |
| 711 | + check(('c:a',), '', '', ('c:a',)) |
| 712 | + check(('c:\\a',), '', '', ('c:\\a',)) |
| 713 | + check(('\\a',), '', '', ('\\a',)) |
| 714 | + |
773 | 715 | def test_root(self):
|
774 | 716 | P = self.cls
|
775 | 717 | self.assertEqual(P('/a/b').root, '/')
|
@@ -860,6 +802,51 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase):
|
860 | 802 | ],
|
861 | 803 | })
|
862 | 804 |
|
| 805 | + def test_drive_root_parts(self): |
| 806 | + check = self._check_drive_root_parts |
| 807 | + # First part is anchored. |
| 808 | + check(('c:',), 'c:', '', ('c:',)) |
| 809 | + check(('c:/',), 'c:', '\\', ('c:\\',)) |
| 810 | + check(('/',), '', '\\', ('\\',)) |
| 811 | + check(('c:a',), 'c:', '', ('c:', 'a')) |
| 812 | + check(('c:/a',), 'c:', '\\', ('c:\\', 'a')) |
| 813 | + check(('/a',), '', '\\', ('\\', 'a')) |
| 814 | + # UNC paths. |
| 815 | + check(('//a/b',), '\\\\a\\b', '\\', ('\\\\a\\b\\',)) |
| 816 | + check(('//a/b/',), '\\\\a\\b', '\\', ('\\\\a\\b\\',)) |
| 817 | + check(('//a/b/c',), '\\\\a\\b', '\\', ('\\\\a\\b\\', 'c')) |
| 818 | + # Second part is anchored, so that the first part is ignored. |
| 819 | + check(('a', 'Z:b', 'c'), 'Z:', '', ('Z:', 'b', 'c')) |
| 820 | + check(('a', 'Z:/b', 'c'), 'Z:', '\\', ('Z:\\', 'b', 'c')) |
| 821 | + # UNC paths. |
| 822 | + check(('a', '//b/c', 'd'), '\\\\b\\c', '\\', ('\\\\b\\c\\', 'd')) |
| 823 | + # Collapsing and stripping excess slashes. |
| 824 | + check(('a', 'Z://b//c/', 'd/'), 'Z:', '\\', ('Z:\\', 'b', 'c', 'd')) |
| 825 | + # UNC paths. |
| 826 | + check(('a', '//b/c//', 'd'), '\\\\b\\c', '\\', ('\\\\b\\c\\', 'd')) |
| 827 | + # Extended paths. |
| 828 | + check(('//?/c:/',), '\\\\?\\c:', '\\', ('\\\\?\\c:\\',)) |
| 829 | + check(('//?/c:/a',), '\\\\?\\c:', '\\', ('\\\\?\\c:\\', 'a')) |
| 830 | + check(('//?/c:/a', '/b'), '\\\\?\\c:', '\\', ('\\\\?\\c:\\', 'b')) |
| 831 | + # Extended UNC paths (format is "\\?\UNC\server\share"). |
| 832 | + check(('//?/UNC/b/c',), '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\',)) |
| 833 | + check(('//?/UNC/b/c/d',), '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\', 'd')) |
| 834 | + # Second part has a root but not drive. |
| 835 | + check(('a', '/b', 'c'), '', '\\', ('\\', 'b', 'c')) |
| 836 | + check(('Z:/a', '/b', 'c'), 'Z:', '\\', ('Z:\\', 'b', 'c')) |
| 837 | + check(('//?/Z:/a', '/b', 'c'), '\\\\?\\Z:', '\\', ('\\\\?\\Z:\\', 'b', 'c')) |
| 838 | + # Joining with the same drive => the first path is appended to if |
| 839 | + # the second path is relative. |
| 840 | + check(('c:/a/b', 'c:x/y'), 'c:', '\\', ('c:\\', 'a', 'b', 'x', 'y')) |
| 841 | + check(('c:/a/b', 'c:/x/y'), 'c:', '\\', ('c:\\', 'x', 'y')) |
| 842 | + # Paths to files with NTFS alternate data streams |
| 843 | + check(('./c:s',), '', '', ('c:s',)) |
| 844 | + check(('cc:s',), '', '', ('cc:s',)) |
| 845 | + check(('C:c:s',), 'C:', '', ('C:', 'c:s')) |
| 846 | + check(('C:/c:s',), 'C:', '\\', ('C:\\', 'c:s')) |
| 847 | + check(('D:a', './c:b'), 'D:', '', ('D:', 'a', 'c:b')) |
| 848 | + check(('D:/a', './c:b'), 'D:', '\\', ('D:\\', 'a', 'c:b')) |
| 849 | + |
863 | 850 | def test_str(self):
|
864 | 851 | p = self.cls('a/b/c')
|
865 | 852 | self.assertEqual(str(p), 'a\\b\\c')
|
|
0 commit comments