@@ -810,6 +810,9 @@ def test_drive_root_parts(self):
810810 check (('c:/a' ,), 'c:' , '\\ ' , ('c:\\ ' , 'a' ))
811811 check (('/a' ,), '' , '\\ ' , ('\\ ' , 'a' ))
812812 # UNC paths.
813+ check (('//' ,), '\\ \\ ' , '' , ('\\ \\ ' ,))
814+ check (('//a' ,), '\\ \\ a' , '' , ('\\ \\ a' ,))
815+ check (('//a/' ,), '\\ \\ a\\ ' , '' , ('\\ \\ a\\ ' ,))
813816 check (('//a/b' ,), '\\ \\ a\\ b' , '\\ ' , ('\\ \\ a\\ b\\ ' ,))
814817 check (('//a/b/' ,), '\\ \\ a\\ b' , '\\ ' , ('\\ \\ a\\ b\\ ' ,))
815818 check (('//a/b/c' ,), '\\ \\ a\\ b' , '\\ ' , ('\\ \\ a\\ b\\ ' , 'c' ))
@@ -823,12 +826,26 @@ def test_drive_root_parts(self):
823826 # UNC paths.
824827 check (('a' , '//b/c//' , 'd' ), '\\ \\ b\\ c' , '\\ ' , ('\\ \\ b\\ c\\ ' , 'd' ))
825828 # Extended paths.
829+ check (('//./c:' ,), '\\ \\ .\\ c:' , '' , ('\\ \\ .\\ c:' ,))
826830 check (('//?/c:/' ,), '\\ \\ ?\\ c:' , '\\ ' , ('\\ \\ ?\\ c:\\ ' ,))
827831 check (('//?/c:/a' ,), '\\ \\ ?\\ c:' , '\\ ' , ('\\ \\ ?\\ c:\\ ' , 'a' ))
828832 check (('//?/c:/a' , '/b' ), '\\ \\ ?\\ c:' , '\\ ' , ('\\ \\ ?\\ c:\\ ' , 'b' ))
829833 # Extended UNC paths (format is "\\?\UNC\server\share").
834+ check (('//?' ,), '\\ \\ ?' , '' , ('\\ \\ ?' ,))
835+ check (('//?/' ,), '\\ \\ ?\\ ' , '' , ('\\ \\ ?\\ ' ,))
836+ check (('//?/UNC' ,), '\\ \\ ?\\ UNC' , '' , ('\\ \\ ?\\ UNC' ,))
837+ check (('//?/UNC/' ,), '\\ \\ ?\\ UNC\\ ' , '' , ('\\ \\ ?\\ UNC\\ ' ,))
838+ check (('//?/UNC/b' ,), '\\ \\ ?\\ UNC\\ b' , '' , ('\\ \\ ?\\ UNC\\ b' ,))
839+ check (('//?/UNC/b/' ,), '\\ \\ ?\\ UNC\\ b\\ ' , '' , ('\\ \\ ?\\ UNC\\ b\\ ' ,))
830840 check (('//?/UNC/b/c' ,), '\\ \\ ?\\ UNC\\ b\\ c' , '\\ ' , ('\\ \\ ?\\ UNC\\ b\\ c\\ ' ,))
841+ check (('//?/UNC/b/c/' ,), '\\ \\ ?\\ UNC\\ b\\ c' , '\\ ' , ('\\ \\ ?\\ UNC\\ b\\ c\\ ' ,))
831842 check (('//?/UNC/b/c/d' ,), '\\ \\ ?\\ UNC\\ b\\ c' , '\\ ' , ('\\ \\ ?\\ UNC\\ b\\ c\\ ' , 'd' ))
843+ # UNC device paths
844+ check (('//./BootPartition/' ,), '\\ \\ .\\ BootPartition' , '\\ ' , ('\\ \\ .\\ BootPartition\\ ' ,))
845+ check (('//?/BootPartition/' ,), '\\ \\ ?\\ BootPartition' , '\\ ' , ('\\ \\ ?\\ BootPartition\\ ' ,))
846+ check (('//./PhysicalDrive0' ,), '\\ \\ .\\ PhysicalDrive0' , '' , ('\\ \\ .\\ PhysicalDrive0' ,))
847+ check (('//?/Volume{}/' ,), '\\ \\ ?\\ Volume{}' , '\\ ' , ('\\ \\ ?\\ Volume{}\\ ' ,))
848+ check (('//./nul' ,), '\\ \\ .\\ nul' , '' , ('\\ \\ .\\ nul' ,))
832849 # Second part has a root but not drive.
833850 check (('a' , '/b' , 'c' ), '' , '\\ ' , ('\\ ' , 'b' , 'c' ))
834851 check (('Z:/a' , '/b' , 'c' ), 'Z:' , '\\ ' , ('Z:\\ ' , 'b' , 'c' ))
@@ -1371,6 +1388,13 @@ def test_join(self):
13711388 self .assertEqual (pp , P ('C:/a/b/dd:s' ))
13721389 pp = p .joinpath (P ('E:d:s' ))
13731390 self .assertEqual (pp , P ('E:d:s' ))
1391+ # Joining onto a UNC path with no root
1392+ pp = P ('//' ).joinpath ('server' )
1393+ self .assertEqual (pp , P ('//server' ))
1394+ pp = P ('//server' ).joinpath ('share' )
1395+ self .assertEqual (pp , P ('//server/share' ))
1396+ pp = P ('//./BootPartition' ).joinpath ('Windows' )
1397+ self .assertEqual (pp , P ('//./BootPartition/Windows' ))
13741398
13751399 def test_div (self ):
13761400 # Basically the same as joinpath().
@@ -2678,20 +2702,20 @@ def setUp(self):
26782702 del self .sub2_tree [1 ][:1 ]
26792703
26802704 def test_walk_topdown (self ):
2681- all = list ( self .walk_path .walk () )
2682-
2683- self . assertEqual ( len ( all ), 4 )
2684- # We can't know which order SUB1 and SUB2 will appear in.
2685- # Not flipped: TESTFN, SUB1, SUB11, SUB2
2686- # flipped: TESTFN, SUB2, SUB1, SUB11
2687- flipped = all [ 0 ][ 1 ][ 0 ] != "SUB1"
2688- all [ 0 ][ 1 ]. sort ( )
2689- all [ 3 - 2 * flipped ][ - 1 ]. sort ( )
2690- all [ 3 - 2 * flipped ] [1 ].sort ()
2691- self . assertEqual ( all [ 0 ], ( self . walk_path , [ "SUB1" , "SUB2" ], [ "tmp1" ]) )
2692- self .assertEqual (all [ 1 + flipped ], ( self .sub1_path , [ "SUB11" ], [ "tmp2" ]) )
2693- self . assertEqual ( all [ 2 + flipped ], ( self .sub11_path , [], []))
2694- self . assertEqual ( all [ 3 - 2 * flipped ], self . sub2_tree )
2705+ walker = self .walk_path .walk ()
2706+ entry = next ( walker )
2707+ entry [ 1 ]. sort () # Ensure we visit SUB1 before SUB2
2708+ self . assertEqual ( entry , ( self . walk_path , [ " SUB1" , " SUB2" ], [ "tmp1" ]))
2709+ entry = next ( walker )
2710+ self . assertEqual ( entry , ( self . sub1_path , [ "SUB11" ], [ "tmp2" ]))
2711+ entry = next ( walker )
2712+ self . assertEqual ( entry , ( self . sub11_path , [], []) )
2713+ entry = next ( walker )
2714+ entry [1 ].sort ()
2715+ entry [ 2 ]. sort ( )
2716+ self .assertEqual (entry , self .sub2_tree )
2717+ with self .assertRaises ( StopIteration ):
2718+ next ( walker )
26952719
26962720 def test_walk_prune (self , walk_path = None ):
26972721 if walk_path is None :
@@ -2715,24 +2739,37 @@ def test_file_like_path(self):
27152739 self .test_walk_prune (FakePath (self .walk_path ).__fspath__ ())
27162740
27172741 def test_walk_bottom_up (self ):
2718- all = list (self .walk_path .walk ( top_down = False ))
2719-
2720- self .assertEqual (len (all ), 4 , all )
2721- # We can't know which order SUB1 and SUB2 will appear in.
2722- # Not flipped: SUB11, SUB1, SUB2, TESTFN
2723- # flipped: SUB2, SUB11, SUB1, TESTFN
2724- flipped = all [3 ][1 ][0 ] != "SUB1"
2725- all [3 ][1 ].sort ()
2726- all [2 - 2 * flipped ][- 1 ].sort ()
2727- all [2 - 2 * flipped ][1 ].sort ()
2728- self .assertEqual (all [3 ],
2729- (self .walk_path , ["SUB1" , "SUB2" ], ["tmp1" ]))
2730- self .assertEqual (all [flipped ],
2731- (self .sub11_path , [], []))
2732- self .assertEqual (all [flipped + 1 ],
2733- (self .sub1_path , ["SUB11" ], ["tmp2" ]))
2734- self .assertEqual (all [2 - 2 * flipped ],
2735- self .sub2_tree )
2742+ seen_testfn = seen_sub1 = seen_sub11 = seen_sub2 = False
2743+ for path , dirnames , filenames in self .walk_path .walk (top_down = False ):
2744+ if path == self .walk_path :
2745+ self .assertFalse (seen_testfn )
2746+ self .assertTrue (seen_sub1 )
2747+ self .assertTrue (seen_sub2 )
2748+ self .assertEqual (sorted (dirnames ), ["SUB1" , "SUB2" ])
2749+ self .assertEqual (filenames , ["tmp1" ])
2750+ seen_testfn = True
2751+ elif path == self .sub1_path :
2752+ self .assertFalse (seen_testfn )
2753+ self .assertFalse (seen_sub1 )
2754+ self .assertTrue (seen_sub11 )
2755+ self .assertEqual (dirnames , ["SUB11" ])
2756+ self .assertEqual (filenames , ["tmp2" ])
2757+ seen_sub1 = True
2758+ elif path == self .sub11_path :
2759+ self .assertFalse (seen_sub1 )
2760+ self .assertFalse (seen_sub11 )
2761+ self .assertEqual (dirnames , [])
2762+ self .assertEqual (filenames , [])
2763+ seen_sub11 = True
2764+ elif path == self .sub2_path :
2765+ self .assertFalse (seen_testfn )
2766+ self .assertFalse (seen_sub2 )
2767+ self .assertEqual (sorted (dirnames ), sorted (self .sub2_tree [1 ]))
2768+ self .assertEqual (sorted (filenames ), sorted (self .sub2_tree [2 ]))
2769+ seen_sub2 = True
2770+ else :
2771+ raise AssertionError (f"Unexpected path: { path } " )
2772+ self .assertTrue (seen_testfn )
27362773
27372774 @os_helper .skip_unless_symlink
27382775 def test_walk_follow_symlinks (self ):
0 commit comments