summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/support/__init__.py16
-rw-r--r--Lib/test/test_os.py43
2 files changed, 53 insertions, 6 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index a631bfc..b718605 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -2178,19 +2178,23 @@ def check_disallow_instantiation(testcase, tp, *args, **kwds):
testcase.assertRaisesRegex(TypeError, msg, tp, *args, **kwds)
@contextlib.contextmanager
+def set_recursion_limit(limit):
+ """Temporarily change the recursion limit."""
+ original_limit = sys.getrecursionlimit()
+ try:
+ sys.setrecursionlimit(limit)
+ yield
+ finally:
+ sys.setrecursionlimit(original_limit)
+
def infinite_recursion(max_depth=75):
"""Set a lower limit for tests that interact with infinite recursions
(e.g test_ast.ASTHelpers_Test.test_recursion_direct) since on some
debug windows builds, due to not enough functions being inlined the
stack size might not handle the default recursion limit (1000). See
bpo-11105 for details."""
+ return set_recursion_limit(max_depth)
- original_depth = sys.getrecursionlimit()
- try:
- sys.setrecursionlimit(max_depth)
- yield
- finally:
- sys.setrecursionlimit(original_depth)
def ignore_deprecations_from(module: str, *, like: str) -> object:
token = object()
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index e057791..e6e25b5 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -33,6 +33,7 @@ from test import support
from test.support import import_helper
from test.support import os_helper
from test.support import socket_helper
+from test.support import set_recursion_limit
from test.support import warnings_helper
from platform import win32_is_iot
@@ -1471,6 +1472,46 @@ class WalkTests(unittest.TestCase):
self.assertEqual(next(it), expected)
p = os.path.join(p, 'd')
+ def test_walk_above_recursion_limit(self):
+ depth = 50
+ os.makedirs(os.path.join(self.walk_path, *(['d'] * depth)))
+ with set_recursion_limit(depth - 5):
+ all = list(self.walk(self.walk_path))
+
+ sub2_path = self.sub2_tree[0]
+ for root, dirs, files in all:
+ if root == sub2_path:
+ dirs.sort()
+ files.sort()
+
+ d_entries = []
+ d_path = self.walk_path
+ for _ in range(depth):
+ d_path = os.path.join(d_path, "d")
+ d_entries.append((d_path, ["d"], []))
+ d_entries[-1][1].clear()
+
+ # Sub-sequences where the order is known
+ sections = {
+ "SUB1": [
+ (self.sub1_path, ["SUB11"], ["tmp2"]),
+ (self.sub11_path, [], []),
+ ],
+ "SUB2": [self.sub2_tree],
+ "d": d_entries,
+ }
+
+ # The ordering of sub-dirs is arbitrary but determines the order in
+ # which sub-sequences appear
+ dirs = all[0][1]
+ expected = [(self.walk_path, dirs, ["tmp1"])]
+ for d in dirs:
+ expected.extend(sections[d])
+
+ self.assertEqual(len(all), depth + 4)
+ self.assertEqual(sorted(dirs), ["SUB1", "SUB2", "d"])
+ self.assertEqual(all, expected)
+
@unittest.skipUnless(hasattr(os, 'fwalk'), "Test needs os.fwalk()")
class FwalkTests(WalkTests):
@@ -1545,6 +1586,8 @@ class FwalkTests(WalkTests):
# fwalk() keeps file descriptors open
test_walk_many_open_files = None
+ # fwalk() still uses recursion
+ test_walk_above_recursion_limit = None
class BytesWalkTests(WalkTests):