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().
This commit is contained in:
parent
dbd23790db
commit
4ea71278ca
@ -1425,84 +1425,6 @@ class PathTest(test_pathlib_abc.DummyPathTest, PurePathTest):
|
||||
with self.assertRaises(TypeError):
|
||||
self.cls(foo="bar")
|
||||
|
||||
def setUpWalk(self):
|
||||
super().setUpWalk()
|
||||
sub21_path= self.sub2_path / "SUB21"
|
||||
tmp5_path = sub21_path / "tmp3"
|
||||
broken_link3_path = self.sub2_path / "broken_link3"
|
||||
|
||||
os.makedirs(sub21_path)
|
||||
tmp5_path.write_text("I am tmp5, blame test_pathlib.")
|
||||
if self.can_symlink:
|
||||
os.symlink(tmp5_path, broken_link3_path)
|
||||
self.sub2_tree[2].append('broken_link3')
|
||||
self.sub2_tree[2].sort()
|
||||
if not is_emscripten:
|
||||
# Emscripten fails with inaccessible directories.
|
||||
os.chmod(sub21_path, 0)
|
||||
try:
|
||||
os.listdir(sub21_path)
|
||||
except PermissionError:
|
||||
self.sub2_tree[1].append('SUB21')
|
||||
else:
|
||||
os.chmod(sub21_path, stat.S_IRWXU)
|
||||
os.unlink(tmp5_path)
|
||||
os.rmdir(sub21_path)
|
||||
|
||||
def test_walk_bad_dir(self):
|
||||
self.setUpWalk()
|
||||
errors = []
|
||||
walk_it = self.walk_path.walk(on_error=errors.append)
|
||||
root, dirs, files = next(walk_it)
|
||||
self.assertEqual(errors, [])
|
||||
dir1 = 'SUB1'
|
||||
path1 = root / dir1
|
||||
path1new = (root / dir1).with_suffix(".new")
|
||||
path1.rename(path1new)
|
||||
try:
|
||||
roots = [r for r, _, _ in walk_it]
|
||||
self.assertTrue(errors)
|
||||
self.assertNotIn(path1, roots)
|
||||
self.assertNotIn(path1new, roots)
|
||||
for dir2 in dirs:
|
||||
if dir2 != dir1:
|
||||
self.assertIn(root / dir2, roots)
|
||||
finally:
|
||||
path1new.rename(path1)
|
||||
|
||||
def test_walk_many_open_files(self):
|
||||
depth = 30
|
||||
base = self.cls(self.base, 'deep')
|
||||
path = self.cls(base, *(['d']*depth))
|
||||
path.mkdir(parents=True)
|
||||
|
||||
iters = [base.walk(top_down=False) for _ in range(100)]
|
||||
for i in range(depth + 1):
|
||||
expected = (path, ['d'] if i else [], [])
|
||||
for it in iters:
|
||||
self.assertEqual(next(it), expected)
|
||||
path = path.parent
|
||||
|
||||
iters = [base.walk(top_down=True) for _ in range(100)]
|
||||
path = base
|
||||
for i in range(depth + 1):
|
||||
expected = (path, ['d'] if i < depth else [], [])
|
||||
for it in iters:
|
||||
self.assertEqual(next(it), expected)
|
||||
path = path / 'd'
|
||||
|
||||
def test_walk_above_recursion_limit(self):
|
||||
recursion_limit = 40
|
||||
# directory_depth > recursion_limit
|
||||
directory_depth = recursion_limit + 10
|
||||
base = self.cls(self.base, 'deep')
|
||||
path = base.joinpath(*(['d'] * directory_depth))
|
||||
path.mkdir(parents=True)
|
||||
|
||||
with infinite_recursion(recursion_limit):
|
||||
list(base.walk())
|
||||
list(base.walk(top_down=False))
|
||||
|
||||
def test_glob_empty_pattern(self):
|
||||
p = self.cls('')
|
||||
with self.assertRaisesRegex(ValueError, 'Unacceptable pattern'):
|
||||
@ -1886,6 +1808,94 @@ class PathTest(test_pathlib_abc.DummyPathTest, PurePathTest):
|
||||
P('c:/').group()
|
||||
|
||||
|
||||
class PathWalkTest(test_pathlib_abc.DummyPathWalkTest):
|
||||
cls = pathlib.Path
|
||||
base = PathTest.base
|
||||
can_symlink = PathTest.can_symlink
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
sub21_path= self.sub2_path / "SUB21"
|
||||
tmp5_path = sub21_path / "tmp3"
|
||||
broken_link3_path = self.sub2_path / "broken_link3"
|
||||
|
||||
os.makedirs(sub21_path)
|
||||
tmp5_path.write_text("I am tmp5, blame test_pathlib.")
|
||||
if self.can_symlink:
|
||||
os.symlink(tmp5_path, broken_link3_path)
|
||||
self.sub2_tree[2].append('broken_link3')
|
||||
self.sub2_tree[2].sort()
|
||||
if not is_emscripten:
|
||||
# Emscripten fails with inaccessible directories.
|
||||
os.chmod(sub21_path, 0)
|
||||
try:
|
||||
os.listdir(sub21_path)
|
||||
except PermissionError:
|
||||
self.sub2_tree[1].append('SUB21')
|
||||
else:
|
||||
os.chmod(sub21_path, stat.S_IRWXU)
|
||||
os.unlink(tmp5_path)
|
||||
os.rmdir(sub21_path)
|
||||
|
||||
def tearDown(self):
|
||||
if 'SUB21' in self.sub2_tree[1]:
|
||||
os.chmod(self.sub2_path / "SUB21", stat.S_IRWXU)
|
||||
super().tearDown()
|
||||
|
||||
def test_walk_bad_dir(self):
|
||||
errors = []
|
||||
walk_it = self.walk_path.walk(on_error=errors.append)
|
||||
root, dirs, files = next(walk_it)
|
||||
self.assertEqual(errors, [])
|
||||
dir1 = 'SUB1'
|
||||
path1 = root / dir1
|
||||
path1new = (root / dir1).with_suffix(".new")
|
||||
path1.rename(path1new)
|
||||
try:
|
||||
roots = [r for r, _, _ in walk_it]
|
||||
self.assertTrue(errors)
|
||||
self.assertNotIn(path1, roots)
|
||||
self.assertNotIn(path1new, roots)
|
||||
for dir2 in dirs:
|
||||
if dir2 != dir1:
|
||||
self.assertIn(root / dir2, roots)
|
||||
finally:
|
||||
path1new.rename(path1)
|
||||
|
||||
def test_walk_many_open_files(self):
|
||||
depth = 30
|
||||
base = self.cls(self.base, 'deep')
|
||||
path = self.cls(base, *(['d']*depth))
|
||||
path.mkdir(parents=True)
|
||||
|
||||
iters = [base.walk(top_down=False) for _ in range(100)]
|
||||
for i in range(depth + 1):
|
||||
expected = (path, ['d'] if i else [], [])
|
||||
for it in iters:
|
||||
self.assertEqual(next(it), expected)
|
||||
path = path.parent
|
||||
|
||||
iters = [base.walk(top_down=True) for _ in range(100)]
|
||||
path = base
|
||||
for i in range(depth + 1):
|
||||
expected = (path, ['d'] if i < depth else [], [])
|
||||
for it in iters:
|
||||
self.assertEqual(next(it), expected)
|
||||
path = path / 'd'
|
||||
|
||||
def test_walk_above_recursion_limit(self):
|
||||
recursion_limit = 40
|
||||
# directory_depth > recursion_limit
|
||||
directory_depth = recursion_limit + 10
|
||||
base = self.cls(self.base, 'deep')
|
||||
path = base.joinpath(*(['d'] * directory_depth))
|
||||
path.mkdir(parents=True)
|
||||
|
||||
with infinite_recursion(recursion_limit):
|
||||
list(base.walk())
|
||||
list(base.walk(top_down=False))
|
||||
|
||||
|
||||
@unittest.skipIf(os.name == 'nt', 'test requires a POSIX-compatible system')
|
||||
class PosixPathTest(PathTest, PurePosixPathTest):
|
||||
cls = pathlib.PosixPath
|
||||
|
@ -2922,7 +2922,16 @@ class DummyPathTest(DummyPurePathTest):
|
||||
filename = tmp / 'foo'
|
||||
self.assertRaises(FileNotFoundError, filename._delete)
|
||||
|
||||
def setUpWalk(self):
|
||||
|
||||
class DummyPathWalkTest(unittest.TestCase):
|
||||
cls = DummyPath
|
||||
base = DummyPathTest.base
|
||||
can_symlink = False
|
||||
|
||||
def setUp(self):
|
||||
name = self.id().split('.')[-1]
|
||||
if name in _tests_needing_symlinks and not self.can_symlink:
|
||||
self.skipTest('requires symlinks')
|
||||
# Build:
|
||||
# TESTFN/
|
||||
# TEST1/ a file kid and two directory kids
|
||||
@ -2966,8 +2975,11 @@ class DummyPathTest(DummyPurePathTest):
|
||||
else:
|
||||
self.sub2_tree = (self.sub2_path, [], ["tmp3"])
|
||||
|
||||
def tearDown(self):
|
||||
base = self.cls(self.base)
|
||||
base._rmtree()
|
||||
|
||||
def test_walk_topdown(self):
|
||||
self.setUpWalk()
|
||||
walker = self.walk_path.walk()
|
||||
entry = next(walker)
|
||||
entry[1].sort() # Ensure we visit SUB1 before SUB2
|
||||
@ -2984,7 +2996,6 @@ class DummyPathTest(DummyPurePathTest):
|
||||
next(walker)
|
||||
|
||||
def test_walk_prune(self):
|
||||
self.setUpWalk()
|
||||
# Prune the search.
|
||||
all = []
|
||||
for root, dirs, files in self.walk_path.walk():
|
||||
@ -3001,7 +3012,6 @@ class DummyPathTest(DummyPurePathTest):
|
||||
self.assertEqual(all[1], self.sub2_tree)
|
||||
|
||||
def test_walk_bottom_up(self):
|
||||
self.setUpWalk()
|
||||
seen_testfn = seen_sub1 = seen_sub11 = seen_sub2 = False
|
||||
for path, dirnames, filenames in self.walk_path.walk(top_down=False):
|
||||
if path == self.walk_path:
|
||||
@ -3036,7 +3046,6 @@ class DummyPathTest(DummyPurePathTest):
|
||||
|
||||
@needs_symlinks
|
||||
def test_walk_follow_symlinks(self):
|
||||
self.setUpWalk()
|
||||
walk_it = self.walk_path.walk(follow_symlinks=True)
|
||||
for root, dirs, files in walk_it:
|
||||
if root == self.link_path:
|
||||
@ -3048,7 +3057,6 @@ class DummyPathTest(DummyPurePathTest):
|
||||
|
||||
@needs_symlinks
|
||||
def test_walk_symlink_location(self):
|
||||
self.setUpWalk()
|
||||
# Tests whether symlinks end up in filenames or dirnames depending
|
||||
# on the `follow_symlinks` argument.
|
||||
walk_it = self.walk_path.walk(follow_symlinks=False)
|
||||
@ -3097,5 +3105,10 @@ class DummyPathWithSymlinksTest(DummyPathTest):
|
||||
can_symlink = True
|
||||
|
||||
|
||||
class DummyPathWithSymlinksWalkTest(DummyPathWalkTest):
|
||||
cls = DummyPathWithSymlinks
|
||||
can_symlink = True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user