gh-108851: Fix tomllib recursion tests (#108853)

* Add get_recursion_available() and get_recursion_depth() functions
  to the test.support module.
* Change infinite_recursion() default max_depth from 75 to 100.
* Fix test_tomllib recursion tests for WASI buildbots: reduce the
  recursion limit and compute the maximum nested array/dict depending
  on the current available recursion limit.
* test.pythoninfo logs sys.getrecursionlimit().
* Enhance test_sys tests on sys.getrecursionlimit()
  and sys.setrecursionlimit().
This commit is contained in:
Victor Stinner 2023-09-06 17:34:31 +02:00 committed by GitHub
parent 2cd170db40
commit 8ff1142578
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 176 additions and 40 deletions

View file

@ -279,20 +279,29 @@ class SysModuleTest(unittest.TestCase):
finally:
sys.setswitchinterval(orig)
def test_recursionlimit(self):
def test_getrecursionlimit(self):
limit = sys.getrecursionlimit()
self.assertIsInstance(limit, int)
self.assertGreater(limit, 1)
self.assertRaises(TypeError, sys.getrecursionlimit, 42)
oldlimit = sys.getrecursionlimit()
self.assertRaises(TypeError, sys.setrecursionlimit)
self.assertRaises(ValueError, sys.setrecursionlimit, -42)
sys.setrecursionlimit(10000)
self.assertEqual(sys.getrecursionlimit(), 10000)
sys.setrecursionlimit(oldlimit)
def test_setrecursionlimit(self):
old_limit = sys.getrecursionlimit()
try:
sys.setrecursionlimit(10_005)
self.assertEqual(sys.getrecursionlimit(), 10_005)
self.assertRaises(TypeError, sys.setrecursionlimit)
self.assertRaises(ValueError, sys.setrecursionlimit, -42)
finally:
sys.setrecursionlimit(old_limit)
def test_recursionlimit_recovery(self):
if hasattr(sys, 'gettrace') and sys.gettrace():
self.skipTest('fatal error if run with a trace function')
oldlimit = sys.getrecursionlimit()
old_limit = sys.getrecursionlimit()
def f():
f()
try:
@ -311,35 +320,31 @@ class SysModuleTest(unittest.TestCase):
with self.assertRaises(RecursionError):
f()
finally:
sys.setrecursionlimit(oldlimit)
sys.setrecursionlimit(old_limit)
@test.support.cpython_only
def test_setrecursionlimit_recursion_depth(self):
def test_setrecursionlimit_to_depth(self):
# Issue #25274: Setting a low recursion limit must be blocked if the
# current recursion depth is already higher than limit.
from _testinternalcapi import get_recursion_depth
def set_recursion_limit_at_depth(depth, limit):
recursion_depth = get_recursion_depth()
if recursion_depth >= depth:
with self.assertRaises(RecursionError) as cm:
sys.setrecursionlimit(limit)
self.assertRegex(str(cm.exception),
"cannot set the recursion limit to [0-9]+ "
"at the recursion depth [0-9]+: "
"the limit is too low")
else:
set_recursion_limit_at_depth(depth, limit)
oldlimit = sys.getrecursionlimit()
old_limit = sys.getrecursionlimit()
try:
sys.setrecursionlimit(1000)
depth = support.get_recursion_depth()
with self.subTest(limit=sys.getrecursionlimit(), depth=depth):
# depth + 1 is OK
sys.setrecursionlimit(depth + 1)
for limit in (10, 25, 50, 75, 100, 150, 200):
set_recursion_limit_at_depth(limit, limit)
# reset the limit to be able to call self.assertRaises()
# context manager
sys.setrecursionlimit(old_limit)
with self.assertRaises(RecursionError) as cm:
sys.setrecursionlimit(depth)
self.assertRegex(str(cm.exception),
"cannot set the recursion limit to [0-9]+ "
"at the recursion depth [0-9]+: "
"the limit is too low")
finally:
sys.setrecursionlimit(oldlimit)
sys.setrecursionlimit(old_limit)
def test_getwindowsversion(self):
# Raise SkipTest if sys doesn't have getwindowsversion attribute