@@ -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