mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
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().
Backport notes:
* Set support.infinite_recursion() minimum to 4 frames.
* test_support.test_get_recursion_depth() uses limit-2, apparently
f-string counts for 2 frames in Python 3.11.
* test_sys.test_setrecursionlimit_to_depth() tests depth+2 instead of
depth+1.
(cherry picked from commit 8ff1142578
)
This commit is contained in:
parent
d61b8f9b8b
commit
95eb9849dd
7 changed files with 183 additions and 41 deletions
|
@ -698,6 +698,85 @@ class TestSupport(unittest.TestCase):
|
|||
else:
|
||||
self.assertTrue(support.has_strftime_extensions)
|
||||
|
||||
def test_get_recursion_depth(self):
|
||||
# test support.get_recursion_depth()
|
||||
code = textwrap.dedent("""
|
||||
from test import support
|
||||
import sys
|
||||
|
||||
def check(cond):
|
||||
if not cond:
|
||||
raise AssertionError("test failed")
|
||||
|
||||
# depth 1
|
||||
check(support.get_recursion_depth() == 1)
|
||||
|
||||
# depth 2
|
||||
def test_func():
|
||||
check(support.get_recursion_depth() == 2)
|
||||
test_func()
|
||||
|
||||
def test_recursive(depth, limit):
|
||||
if depth >= limit:
|
||||
# cannot call get_recursion_depth() at this depth,
|
||||
# it can raise RecursionError
|
||||
return
|
||||
get_depth = support.get_recursion_depth()
|
||||
print(f"test_recursive: {depth}/{limit}: "
|
||||
f"get_recursion_depth() says {get_depth}")
|
||||
check(get_depth == depth)
|
||||
test_recursive(depth + 1, limit)
|
||||
|
||||
# depth up to 25
|
||||
with support.infinite_recursion(max_depth=25):
|
||||
limit = sys.getrecursionlimit()
|
||||
print(f"test with sys.getrecursionlimit()={limit}")
|
||||
# Use limit-2 since f-string seems to consume 2 frames.
|
||||
test_recursive(2, limit - 2)
|
||||
|
||||
# depth up to 500
|
||||
with support.infinite_recursion(max_depth=500):
|
||||
limit = sys.getrecursionlimit()
|
||||
print(f"test with sys.getrecursionlimit()={limit}")
|
||||
# limit-2 since f-string seems to consume 2 frames
|
||||
test_recursive(2, limit - 2)
|
||||
""")
|
||||
script_helper.assert_python_ok("-c", code)
|
||||
|
||||
def test_recursion(self):
|
||||
# Test infinite_recursion() and get_recursion_available() functions.
|
||||
def recursive_function(depth):
|
||||
if depth:
|
||||
recursive_function(depth - 1)
|
||||
|
||||
for max_depth in (5, 25, 250):
|
||||
with support.infinite_recursion(max_depth):
|
||||
available = support.get_recursion_available()
|
||||
|
||||
# Recursion up to 'available' additional frames should be OK.
|
||||
recursive_function(available)
|
||||
|
||||
# Recursion up to 'available+1' additional frames must raise
|
||||
# RecursionError. Avoid self.assertRaises(RecursionError) which
|
||||
# can consume more than 3 frames and so raises RecursionError.
|
||||
try:
|
||||
recursive_function(available + 1)
|
||||
except RecursionError:
|
||||
pass
|
||||
else:
|
||||
self.fail("RecursionError was not raised")
|
||||
|
||||
# Test the bare minimumum: max_depth=4
|
||||
with support.infinite_recursion(4):
|
||||
try:
|
||||
recursive_function(4)
|
||||
except RecursionError:
|
||||
pass
|
||||
else:
|
||||
self.fail("RecursionError was not raised")
|
||||
|
||||
#self.assertEqual(available, 2)
|
||||
|
||||
# XXX -follows a list of untested API
|
||||
# make_legacy_pyc
|
||||
# is_resource_enabled
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue