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