Skip to content

Commit 4ea7127

Browse files
authored
pathlib tests: move walk() tests into their own classes (GH-126651)
Move tests for Path.walk() into a new PathWalkTest class, and apply a similar change in tests for the ABCs. This allows us to properly tear down the walk test hierarchy in tearDown(), rather than leaving it to os_helper.rmtree().
1 parent dbd2379 commit 4ea7127

File tree

2 files changed

+107
-84
lines changed

2 files changed

+107
-84
lines changed

Lib/test/test_pathlib/test_pathlib.py

+88-78
Original file line numberDiff line numberDiff line change
@@ -1425,84 +1425,6 @@ def test_passing_kwargs_errors(self):
14251425
with self.assertRaises(TypeError):
14261426
self.cls(foo="bar")
14271427

1428-
def setUpWalk(self):
1429-
super().setUpWalk()
1430-
sub21_path= self.sub2_path / "SUB21"
1431-
tmp5_path = sub21_path / "tmp3"
1432-
broken_link3_path = self.sub2_path / "broken_link3"
1433-
1434-
os.makedirs(sub21_path)
1435-
tmp5_path.write_text("I am tmp5, blame test_pathlib.")
1436-
if self.can_symlink:
1437-
os.symlink(tmp5_path, broken_link3_path)
1438-
self.sub2_tree[2].append('broken_link3')
1439-
self.sub2_tree[2].sort()
1440-
if not is_emscripten:
1441-
# Emscripten fails with inaccessible directories.
1442-
os.chmod(sub21_path, 0)
1443-
try:
1444-
os.listdir(sub21_path)
1445-
except PermissionError:
1446-
self.sub2_tree[1].append('SUB21')
1447-
else:
1448-
os.chmod(sub21_path, stat.S_IRWXU)
1449-
os.unlink(tmp5_path)
1450-
os.rmdir(sub21_path)
1451-
1452-
def test_walk_bad_dir(self):
1453-
self.setUpWalk()
1454-
errors = []
1455-
walk_it = self.walk_path.walk(on_error=errors.append)
1456-
root, dirs, files = next(walk_it)
1457-
self.assertEqual(errors, [])
1458-
dir1 = 'SUB1'
1459-
path1 = root / dir1
1460-
path1new = (root / dir1).with_suffix(".new")
1461-
path1.rename(path1new)
1462-
try:
1463-
roots = [r for r, _, _ in walk_it]
1464-
self.assertTrue(errors)
1465-
self.assertNotIn(path1, roots)
1466-
self.assertNotIn(path1new, roots)
1467-
for dir2 in dirs:
1468-
if dir2 != dir1:
1469-
self.assertIn(root / dir2, roots)
1470-
finally:
1471-
path1new.rename(path1)
1472-
1473-
def test_walk_many_open_files(self):
1474-
depth = 30
1475-
base = self.cls(self.base, 'deep')
1476-
path = self.cls(base, *(['d']*depth))
1477-
path.mkdir(parents=True)
1478-
1479-
iters = [base.walk(top_down=False) for _ in range(100)]
1480-
for i in range(depth + 1):
1481-
expected = (path, ['d'] if i else [], [])
1482-
for it in iters:
1483-
self.assertEqual(next(it), expected)
1484-
path = path.parent
1485-
1486-
iters = [base.walk(top_down=True) for _ in range(100)]
1487-
path = base
1488-
for i in range(depth + 1):
1489-
expected = (path, ['d'] if i < depth else [], [])
1490-
for it in iters:
1491-
self.assertEqual(next(it), expected)
1492-
path = path / 'd'
1493-
1494-
def test_walk_above_recursion_limit(self):
1495-
recursion_limit = 40
1496-
# directory_depth > recursion_limit
1497-
directory_depth = recursion_limit + 10
1498-
base = self.cls(self.base, 'deep')
1499-
path = base.joinpath(*(['d'] * directory_depth))
1500-
path.mkdir(parents=True)
1501-
1502-
with infinite_recursion(recursion_limit):
1503-
list(base.walk())
1504-
list(base.walk(top_down=False))
1505-
15061428
def test_glob_empty_pattern(self):
15071429
p = self.cls('')
15081430
with self.assertRaisesRegex(ValueError, 'Unacceptable pattern'):
@@ -1886,6 +1808,94 @@ def test_group_windows(self):
18861808
P('c:/').group()
18871809

18881810

1811+
class PathWalkTest(test_pathlib_abc.DummyPathWalkTest):
1812+
cls = pathlib.Path
1813+
base = PathTest.base
1814+
can_symlink = PathTest.can_symlink
1815+
1816+
def setUp(self):
1817+
super().setUp()
1818+
sub21_path= self.sub2_path / "SUB21"
1819+
tmp5_path = sub21_path / "tmp3"
1820+
broken_link3_path = self.sub2_path / "broken_link3"
1821+
1822+
os.makedirs(sub21_path)
1823+
tmp5_path.write_text("I am tmp5, blame test_pathlib.")
1824+
if self.can_symlink:
1825+
os.symlink(tmp5_path, broken_link3_path)
1826+
self.sub2_tree[2].append('broken_link3')
1827+
self.sub2_tree[2].sort()
1828+
if not is_emscripten:
1829+
# Emscripten fails with inaccessible directories.
1830+
os.chmod(sub21_path, 0)
1831+
try:
1832+
os.listdir(sub21_path)
1833+
except PermissionError:
1834+
self.sub2_tree[1].append('SUB21')
1835+
else:
1836+
os.chmod(sub21_path, stat.S_IRWXU)
1837+
os.unlink(tmp5_path)
1838+
os.rmdir(sub21_path)
1839+
1840+
def tearDown(self):
1841+
if 'SUB21' in self.sub2_tree[1]:
1842+
os.chmod(self.sub2_path / "SUB21", stat.S_IRWXU)
1843+
super().tearDown()
1844+
1845+
def test_walk_bad_dir(self):
1846+
errors = []
1847+
walk_it = self.walk_path.walk(on_error=errors.append)
1848+
root, dirs, files = next(walk_it)
1849+
self.assertEqual(errors, [])
1850+
dir1 = 'SUB1'
1851+
path1 = root / dir1
1852+
path1new = (root / dir1).with_suffix(".new")
1853+
path1.rename(path1new)
1854+
try:
1855+
roots = [r for r, _, _ in walk_it]
1856+
self.assertTrue(errors)
1857+
self.assertNotIn(path1, roots)
1858+
self.assertNotIn(path1new, roots)
1859+
for dir2 in dirs:
1860+
if dir2 != dir1:
1861+
self.assertIn(root / dir2, roots)
1862+
finally:
1863+
path1new.rename(path1)
1864+
1865+
def test_walk_many_open_files(self):
1866+
depth = 30
1867+
base = self.cls(self.base, 'deep')
1868+
path = self.cls(base, *(['d']*depth))
1869+
path.mkdir(parents=True)
1870+
1871+
iters = [base.walk(top_down=False) for _ in range(100)]
1872+
for i in range(depth + 1):
1873+
expected = (path, ['d'] if i else [], [])
1874+
for it in iters:
1875+
self.assertEqual(next(it), expected)
1876+
path = path.parent
1877+
1878+
iters = [base.walk(top_down=True) for _ in range(100)]
1879+
path = base
1880+
for i in range(depth + 1):
1881+
expected = (path, ['d'] if i < depth else [], [])
1882+
for it in iters:
1883+
self.assertEqual(next(it), expected)
1884+
path = path / 'd'
1885+
1886+
def test_walk_above_recursion_limit(self):
1887+
recursion_limit = 40
1888+
# directory_depth > recursion_limit
1889+
directory_depth = recursion_limit + 10
1890+
base = self.cls(self.base, 'deep')
1891+
path = base.joinpath(*(['d'] * directory_depth))
1892+
path.mkdir(parents=True)
1893+
1894+
with infinite_recursion(recursion_limit):
1895+
list(base.walk())
1896+
list(base.walk(top_down=False))
1897+
1898+
18891899
@unittest.skipIf(os.name == 'nt', 'test requires a POSIX-compatible system')
18901900
class PosixPathTest(PathTest, PurePosixPathTest):
18911901
cls = pathlib.PosixPath

Lib/test/test_pathlib/test_pathlib_abc.py

+19-6
Original file line numberDiff line numberDiff line change
@@ -2922,7 +2922,16 @@ def test_delete_missing(self):
29222922
filename = tmp / 'foo'
29232923
self.assertRaises(FileNotFoundError, filename._delete)
29242924

2925-
def setUpWalk(self):
2925+
2926+
class DummyPathWalkTest(unittest.TestCase):
2927+
cls = DummyPath
2928+
base = DummyPathTest.base
2929+
can_symlink = False
2930+
2931+
def setUp(self):
2932+
name = self.id().split('.')[-1]
2933+
if name in _tests_needing_symlinks and not self.can_symlink:
2934+
self.skipTest('requires symlinks')
29262935
# Build:
29272936
# TESTFN/
29282937
# TEST1/ a file kid and two directory kids
@@ -2966,8 +2975,11 @@ def setUpWalk(self):
29662975
else:
29672976
self.sub2_tree = (self.sub2_path, [], ["tmp3"])
29682977

2978+
def tearDown(self):
2979+
base = self.cls(self.base)
2980+
base._rmtree()
2981+
29692982
def test_walk_topdown(self):
2970-
self.setUpWalk()
29712983
walker = self.walk_path.walk()
29722984
entry = next(walker)
29732985
entry[1].sort() # Ensure we visit SUB1 before SUB2
@@ -2984,7 +2996,6 @@ def test_walk_topdown(self):
29842996
next(walker)
29852997

29862998
def test_walk_prune(self):
2987-
self.setUpWalk()
29882999
# Prune the search.
29893000
all = []
29903001
for root, dirs, files in self.walk_path.walk():
@@ -3001,7 +3012,6 @@ def test_walk_prune(self):
30013012
self.assertEqual(all[1], self.sub2_tree)
30023013

30033014
def test_walk_bottom_up(self):
3004-
self.setUpWalk()
30053015
seen_testfn = seen_sub1 = seen_sub11 = seen_sub2 = False
30063016
for path, dirnames, filenames in self.walk_path.walk(top_down=False):
30073017
if path == self.walk_path:
@@ -3036,7 +3046,6 @@ def test_walk_bottom_up(self):
30363046

30373047
@needs_symlinks
30383048
def test_walk_follow_symlinks(self):
3039-
self.setUpWalk()
30403049
walk_it = self.walk_path.walk(follow_symlinks=True)
30413050
for root, dirs, files in walk_it:
30423051
if root == self.link_path:
@@ -3048,7 +3057,6 @@ def test_walk_follow_symlinks(self):
30483057

30493058
@needs_symlinks
30503059
def test_walk_symlink_location(self):
3051-
self.setUpWalk()
30523060
# Tests whether symlinks end up in filenames or dirnames depending
30533061
# on the `follow_symlinks` argument.
30543062
walk_it = self.walk_path.walk(follow_symlinks=False)
@@ -3097,5 +3105,10 @@ class DummyPathWithSymlinksTest(DummyPathTest):
30973105
can_symlink = True
30983106

30993107

3108+
class DummyPathWithSymlinksWalkTest(DummyPathWalkTest):
3109+
cls = DummyPathWithSymlinks
3110+
can_symlink = True
3111+
3112+
31003113
if __name__ == "__main__":
31013114
unittest.main()

0 commit comments

Comments
 (0)