Skip to content

Commit 81bc802

Browse files
authored
GH-110109: Move tests for pathlib.Path.walk() into main test classes. (#110655)
1 parent 2655369 commit 81bc802

File tree

1 file changed

+169
-169
lines changed

1 file changed

+169
-169
lines changed

Lib/test/test_pathlib.py

+169-169
Original file line numberDiff line numberDiff line change
@@ -2620,6 +2620,164 @@ def test_complex_symlinks_relative(self):
26202620
def test_complex_symlinks_relative_dot_dot(self):
26212621
self._check_complex_symlinks(os.path.join('dirA', '..'))
26222622

2623+
def setUpWalk(self):
2624+
# Build:
2625+
# TESTFN/
2626+
# TEST1/ a file kid and two directory kids
2627+
# tmp1
2628+
# SUB1/ a file kid and a directory kid
2629+
# tmp2
2630+
# SUB11/ no kids
2631+
# SUB2/ a file kid and a dirsymlink kid
2632+
# tmp3
2633+
# link/ a symlink to TEST2
2634+
# broken_link
2635+
# broken_link2
2636+
# TEST2/
2637+
# tmp4 a lone file
2638+
self.walk_path = self.cls(BASE, "TEST1")
2639+
self.sub1_path = self.walk_path / "SUB1"
2640+
self.sub11_path = self.sub1_path / "SUB11"
2641+
self.sub2_path = self.walk_path / "SUB2"
2642+
tmp1_path = self.walk_path / "tmp1"
2643+
tmp2_path = self.sub1_path / "tmp2"
2644+
tmp3_path = self.sub2_path / "tmp3"
2645+
self.link_path = self.sub2_path / "link"
2646+
t2_path = self.cls(BASE, "TEST2")
2647+
tmp4_path = self.cls(BASE, "TEST2", "tmp4")
2648+
broken_link_path = self.sub2_path / "broken_link"
2649+
broken_link2_path = self.sub2_path / "broken_link2"
2650+
2651+
self.sub11_path.mkdir(parents=True)
2652+
self.sub2_path.mkdir(parents=True)
2653+
t2_path.mkdir(parents=True)
2654+
2655+
for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path:
2656+
with path.open("w", encoding='utf-8') as f:
2657+
f.write(f"I'm {path} and proud of it. Blame test_pathlib.\n")
2658+
2659+
if self.can_symlink:
2660+
self.link_path.symlink_to(t2_path)
2661+
broken_link_path.symlink_to('broken')
2662+
broken_link2_path.symlink_to(self.cls('tmp3', 'broken'))
2663+
self.sub2_tree = (self.sub2_path, [], ["broken_link", "broken_link2", "link", "tmp3"])
2664+
else:
2665+
self.sub2_tree = (self.sub2_path, [], ["tmp3"])
2666+
2667+
def test_walk_topdown(self):
2668+
self.setUpWalk()
2669+
walker = self.walk_path.walk()
2670+
entry = next(walker)
2671+
entry[1].sort() # Ensure we visit SUB1 before SUB2
2672+
self.assertEqual(entry, (self.walk_path, ["SUB1", "SUB2"], ["tmp1"]))
2673+
entry = next(walker)
2674+
self.assertEqual(entry, (self.sub1_path, ["SUB11"], ["tmp2"]))
2675+
entry = next(walker)
2676+
self.assertEqual(entry, (self.sub11_path, [], []))
2677+
entry = next(walker)
2678+
entry[1].sort()
2679+
entry[2].sort()
2680+
self.assertEqual(entry, self.sub2_tree)
2681+
with self.assertRaises(StopIteration):
2682+
next(walker)
2683+
2684+
def test_walk_prune(self):
2685+
self.setUpWalk()
2686+
# Prune the search.
2687+
all = []
2688+
for root, dirs, files in self.walk_path.walk():
2689+
all.append((root, dirs, files))
2690+
if 'SUB1' in dirs:
2691+
# Note that this also mutates the dirs we appended to all!
2692+
dirs.remove('SUB1')
2693+
2694+
self.assertEqual(len(all), 2)
2695+
self.assertEqual(all[0], (self.walk_path, ["SUB2"], ["tmp1"]))
2696+
2697+
all[1][-1].sort()
2698+
all[1][1].sort()
2699+
self.assertEqual(all[1], self.sub2_tree)
2700+
2701+
def test_walk_bottom_up(self):
2702+
self.setUpWalk()
2703+
seen_testfn = seen_sub1 = seen_sub11 = seen_sub2 = False
2704+
for path, dirnames, filenames in self.walk_path.walk(top_down=False):
2705+
if path == self.walk_path:
2706+
self.assertFalse(seen_testfn)
2707+
self.assertTrue(seen_sub1)
2708+
self.assertTrue(seen_sub2)
2709+
self.assertEqual(sorted(dirnames), ["SUB1", "SUB2"])
2710+
self.assertEqual(filenames, ["tmp1"])
2711+
seen_testfn = True
2712+
elif path == self.sub1_path:
2713+
self.assertFalse(seen_testfn)
2714+
self.assertFalse(seen_sub1)
2715+
self.assertTrue(seen_sub11)
2716+
self.assertEqual(dirnames, ["SUB11"])
2717+
self.assertEqual(filenames, ["tmp2"])
2718+
seen_sub1 = True
2719+
elif path == self.sub11_path:
2720+
self.assertFalse(seen_sub1)
2721+
self.assertFalse(seen_sub11)
2722+
self.assertEqual(dirnames, [])
2723+
self.assertEqual(filenames, [])
2724+
seen_sub11 = True
2725+
elif path == self.sub2_path:
2726+
self.assertFalse(seen_testfn)
2727+
self.assertFalse(seen_sub2)
2728+
self.assertEqual(sorted(dirnames), sorted(self.sub2_tree[1]))
2729+
self.assertEqual(sorted(filenames), sorted(self.sub2_tree[2]))
2730+
seen_sub2 = True
2731+
else:
2732+
raise AssertionError(f"Unexpected path: {path}")
2733+
self.assertTrue(seen_testfn)
2734+
2735+
def test_walk_follow_symlinks(self):
2736+
if not self.can_symlink:
2737+
self.skipTest("symlinks required")
2738+
self.setUpWalk()
2739+
walk_it = self.walk_path.walk(follow_symlinks=True)
2740+
for root, dirs, files in walk_it:
2741+
if root == self.link_path:
2742+
self.assertEqual(dirs, [])
2743+
self.assertEqual(files, ["tmp4"])
2744+
break
2745+
else:
2746+
self.fail("Didn't follow symlink with follow_symlinks=True")
2747+
2748+
def test_walk_symlink_location(self):
2749+
if not self.can_symlink:
2750+
self.skipTest("symlinks required")
2751+
self.setUpWalk()
2752+
# Tests whether symlinks end up in filenames or dirnames depending
2753+
# on the `follow_symlinks` argument.
2754+
walk_it = self.walk_path.walk(follow_symlinks=False)
2755+
for root, dirs, files in walk_it:
2756+
if root == self.sub2_path:
2757+
self.assertIn("link", files)
2758+
break
2759+
else:
2760+
self.fail("symlink not found")
2761+
2762+
walk_it = self.walk_path.walk(follow_symlinks=True)
2763+
for root, dirs, files in walk_it:
2764+
if root == self.sub2_path:
2765+
self.assertIn("link", dirs)
2766+
break
2767+
else:
2768+
self.fail("symlink not found")
2769+
2770+
def test_walk_above_recursion_limit(self):
2771+
recursion_limit = 40
2772+
# directory_depth > recursion_limit
2773+
directory_depth = recursion_limit + 10
2774+
base = self.cls(BASE, 'deep')
2775+
path = self.cls(base, *(['d'] * directory_depth))
2776+
path.mkdir(parents=True)
2777+
2778+
with set_recursion_limit(recursion_limit):
2779+
list(base.walk())
2780+
list(base.walk(top_down=False))
26232781

26242782
class DummyPathWithSymlinks(DummyPath):
26252783
def readlink(self):
@@ -3193,178 +3351,32 @@ def test_passing_kwargs_deprecated(self):
31933351
with self.assertWarns(DeprecationWarning):
31943352
self.cls(foo="bar")
31953353

3196-
3197-
class WalkTests(unittest.TestCase):
3198-
3199-
def setUp(self):
3200-
self.addCleanup(os_helper.rmtree, os_helper.TESTFN)
3201-
3202-
# Build:
3203-
# TESTFN/
3204-
# TEST1/ a file kid and two directory kids
3205-
# tmp1
3206-
# SUB1/ a file kid and a directory kid
3207-
# tmp2
3208-
# SUB11/ no kids
3209-
# SUB2/ a file kid and a dirsymlink kid
3210-
# tmp3
3211-
# SUB21/ not readable
3212-
# tmp5
3213-
# link/ a symlink to TEST2
3214-
# broken_link
3215-
# broken_link2
3216-
# broken_link3
3217-
# TEST2/
3218-
# tmp4 a lone file
3219-
self.walk_path = pathlib.Path(os_helper.TESTFN, "TEST1")
3220-
self.sub1_path = self.walk_path / "SUB1"
3221-
self.sub11_path = self.sub1_path / "SUB11"
3222-
self.sub2_path = self.walk_path / "SUB2"
3354+
def setUpWalk(self):
3355+
super().setUpWalk()
32233356
sub21_path= self.sub2_path / "SUB21"
3224-
tmp1_path = self.walk_path / "tmp1"
3225-
tmp2_path = self.sub1_path / "tmp2"
3226-
tmp3_path = self.sub2_path / "tmp3"
32273357
tmp5_path = sub21_path / "tmp3"
3228-
self.link_path = self.sub2_path / "link"
3229-
t2_path = pathlib.Path(os_helper.TESTFN, "TEST2")
3230-
tmp4_path = pathlib.Path(os_helper.TESTFN, "TEST2", "tmp4")
3231-
broken_link_path = self.sub2_path / "broken_link"
3232-
broken_link2_path = self.sub2_path / "broken_link2"
32333358
broken_link3_path = self.sub2_path / "broken_link3"
32343359

3235-
os.makedirs(self.sub11_path)
3236-
os.makedirs(self.sub2_path)
32373360
os.makedirs(sub21_path)
3238-
os.makedirs(t2_path)
3239-
3240-
for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path, tmp5_path:
3241-
with open(path, "x", encoding='utf-8') as f:
3242-
f.write(f"I'm {path} and proud of it. Blame test_pathlib.\n")
3243-
3244-
if os_helper.can_symlink():
3245-
os.symlink(os.path.abspath(t2_path), self.link_path)
3246-
os.symlink('broken', broken_link_path, True)
3247-
os.symlink(pathlib.Path('tmp3', 'broken'), broken_link2_path, True)
3248-
os.symlink(pathlib.Path('SUB21', 'tmp5'), broken_link3_path, True)
3249-
self.sub2_tree = (self.sub2_path, ["SUB21"],
3250-
["broken_link", "broken_link2", "broken_link3",
3251-
"link", "tmp3"])
3252-
else:
3253-
self.sub2_tree = (self.sub2_path, ["SUB21"], ["tmp3"])
3254-
3361+
tmp5_path.write_text("I am tmp5, blame test_pathlib.")
3362+
if self.can_symlink:
3363+
os.symlink(tmp5_path, broken_link3_path)
3364+
self.sub2_tree[2].append('broken_link3')
3365+
self.sub2_tree[2].sort()
32553366
if not is_emscripten:
32563367
# Emscripten fails with inaccessible directories.
32573368
os.chmod(sub21_path, 0)
32583369
try:
32593370
os.listdir(sub21_path)
32603371
except PermissionError:
3261-
self.addCleanup(os.chmod, sub21_path, stat.S_IRWXU)
3372+
self.sub2_tree[1].append('SUB21')
32623373
else:
32633374
os.chmod(sub21_path, stat.S_IRWXU)
32643375
os.unlink(tmp5_path)
32653376
os.rmdir(sub21_path)
3266-
del self.sub2_tree[1][:1]
3267-
3268-
def test_walk_topdown(self):
3269-
walker = self.walk_path.walk()
3270-
entry = next(walker)
3271-
entry[1].sort() # Ensure we visit SUB1 before SUB2
3272-
self.assertEqual(entry, (self.walk_path, ["SUB1", "SUB2"], ["tmp1"]))
3273-
entry = next(walker)
3274-
self.assertEqual(entry, (self.sub1_path, ["SUB11"], ["tmp2"]))
3275-
entry = next(walker)
3276-
self.assertEqual(entry, (self.sub11_path, [], []))
3277-
entry = next(walker)
3278-
entry[1].sort()
3279-
entry[2].sort()
3280-
self.assertEqual(entry, self.sub2_tree)
3281-
with self.assertRaises(StopIteration):
3282-
next(walker)
3283-
3284-
def test_walk_prune(self, walk_path=None):
3285-
if walk_path is None:
3286-
walk_path = self.walk_path
3287-
# Prune the search.
3288-
all = []
3289-
for root, dirs, files in walk_path.walk():
3290-
all.append((root, dirs, files))
3291-
if 'SUB1' in dirs:
3292-
# Note that this also mutates the dirs we appended to all!
3293-
dirs.remove('SUB1')
3294-
3295-
self.assertEqual(len(all), 2)
3296-
self.assertEqual(all[0], (self.walk_path, ["SUB2"], ["tmp1"]))
3297-
3298-
all[1][-1].sort()
3299-
all[1][1].sort()
3300-
self.assertEqual(all[1], self.sub2_tree)
3301-
3302-
def test_file_like_path(self):
3303-
self.test_walk_prune(FakePath(self.walk_path).__fspath__())
3304-
3305-
def test_walk_bottom_up(self):
3306-
seen_testfn = seen_sub1 = seen_sub11 = seen_sub2 = False
3307-
for path, dirnames, filenames in self.walk_path.walk(top_down=False):
3308-
if path == self.walk_path:
3309-
self.assertFalse(seen_testfn)
3310-
self.assertTrue(seen_sub1)
3311-
self.assertTrue(seen_sub2)
3312-
self.assertEqual(sorted(dirnames), ["SUB1", "SUB2"])
3313-
self.assertEqual(filenames, ["tmp1"])
3314-
seen_testfn = True
3315-
elif path == self.sub1_path:
3316-
self.assertFalse(seen_testfn)
3317-
self.assertFalse(seen_sub1)
3318-
self.assertTrue(seen_sub11)
3319-
self.assertEqual(dirnames, ["SUB11"])
3320-
self.assertEqual(filenames, ["tmp2"])
3321-
seen_sub1 = True
3322-
elif path == self.sub11_path:
3323-
self.assertFalse(seen_sub1)
3324-
self.assertFalse(seen_sub11)
3325-
self.assertEqual(dirnames, [])
3326-
self.assertEqual(filenames, [])
3327-
seen_sub11 = True
3328-
elif path == self.sub2_path:
3329-
self.assertFalse(seen_testfn)
3330-
self.assertFalse(seen_sub2)
3331-
self.assertEqual(sorted(dirnames), sorted(self.sub2_tree[1]))
3332-
self.assertEqual(sorted(filenames), sorted(self.sub2_tree[2]))
3333-
seen_sub2 = True
3334-
else:
3335-
raise AssertionError(f"Unexpected path: {path}")
3336-
self.assertTrue(seen_testfn)
3337-
3338-
@os_helper.skip_unless_symlink
3339-
def test_walk_follow_symlinks(self):
3340-
walk_it = self.walk_path.walk(follow_symlinks=True)
3341-
for root, dirs, files in walk_it:
3342-
if root == self.link_path:
3343-
self.assertEqual(dirs, [])
3344-
self.assertEqual(files, ["tmp4"])
3345-
break
3346-
else:
3347-
self.fail("Didn't follow symlink with follow_symlinks=True")
3348-
3349-
@os_helper.skip_unless_symlink
3350-
def test_walk_symlink_location(self):
3351-
# Tests whether symlinks end up in filenames or dirnames depending
3352-
# on the `follow_symlinks` argument.
3353-
walk_it = self.walk_path.walk(follow_symlinks=False)
3354-
for root, dirs, files in walk_it:
3355-
if root == self.sub2_path:
3356-
self.assertIn("link", files)
3357-
break
3358-
else:
3359-
self.fail("symlink not found")
3360-
3361-
walk_it = self.walk_path.walk(follow_symlinks=True)
3362-
for root, dirs, files in walk_it:
3363-
if root == self.sub2_path:
3364-
self.assertIn("link", dirs)
3365-
break
33663377

33673378
def test_walk_bad_dir(self):
3379+
self.setUpWalk()
33683380
errors = []
33693381
walk_it = self.walk_path.walk(on_error=errors.append)
33703382
root, dirs, files = next(walk_it)
@@ -3386,8 +3398,8 @@ def test_walk_bad_dir(self):
33863398

33873399
def test_walk_many_open_files(self):
33883400
depth = 30
3389-
base = pathlib.Path(os_helper.TESTFN, 'deep')
3390-
path = pathlib.Path(base, *(['d']*depth))
3401+
base = self.cls(BASE, 'deep')
3402+
path = self.cls(base, *(['d']*depth))
33913403
path.mkdir(parents=True)
33923404

33933405
iters = [base.walk(top_down=False) for _ in range(100)]
@@ -3405,18 +3417,6 @@ def test_walk_many_open_files(self):
34053417
self.assertEqual(next(it), expected)
34063418
path = path / 'd'
34073419

3408-
def test_walk_above_recursion_limit(self):
3409-
recursion_limit = 40
3410-
# directory_depth > recursion_limit
3411-
directory_depth = recursion_limit + 10
3412-
base = pathlib.Path(os_helper.TESTFN, 'deep')
3413-
path = pathlib.Path(base, *(['d'] * directory_depth))
3414-
path.mkdir(parents=True)
3415-
3416-
with set_recursion_limit(recursion_limit):
3417-
list(base.walk())
3418-
list(base.walk(top_down=False))
3419-
34203420

34213421
@only_posix
34223422
class PosixPathTest(PathTest):

0 commit comments

Comments
 (0)