GH-111808: Make the default value for test.support.infinite_recursion() conditional on compiler optimizations (GH-112223)

Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
Brett Cannon 2023-11-17 15:52:11 -08:00 committed by GitHub
parent dabc0d77b2
commit f489ace9e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 4 deletions

View file

@ -2120,13 +2120,21 @@ def set_recursion_limit(limit):
finally: finally:
sys.setrecursionlimit(original_limit) sys.setrecursionlimit(original_limit)
def infinite_recursion(max_depth=100): def infinite_recursion(max_depth=None):
"""Set a lower limit for tests that interact with infinite recursions """Set a lower limit for tests that interact with infinite recursions
(e.g test_ast.ASTHelpers_Test.test_recursion_direct) since on some (e.g test_ast.ASTHelpers_Test.test_recursion_direct) since on some
debug windows builds, due to not enough functions being inlined the debug windows builds, due to not enough functions being inlined the
stack size might not handle the default recursion limit (1000). See stack size might not handle the default recursion limit (1000). See
bpo-11105 for details.""" bpo-11105 for details."""
if max_depth < 3: if max_depth is None:
if not python_is_optimized() or Py_DEBUG:
# Python built without compiler optimizations or in debug mode
# usually consumes more stack memory per function call.
# Unoptimized number based on what works under a WASI debug build.
max_depth = 50
else:
max_depth = 100
elif max_depth < 3:
raise ValueError("max_depth must be at least 3, got {max_depth}") raise ValueError("max_depth must be at least 3, got {max_depth}")
depth = get_recursion_depth() depth = get_recursion_depth()
depth = max(depth - 1, 1) # Ignore infinite_recursion() frame. depth = max(depth - 1, 1) # Ignore infinite_recursion() frame.

View file

@ -221,7 +221,7 @@ def do(bad):
self.assertRaises(Exc, func, Bad()) self.assertRaises(Exc, func, Bad())
@support.no_tracing @support.no_tracing
@support.infinite_recursion(25) @support.infinite_recursion()
def test_recursion(self): def test_recursion(self):
# Check that comparison for recursive objects fails gracefully # Check that comparison for recursive objects fails gracefully
from collections import UserList from collections import UserList

View file

@ -5621,7 +5621,7 @@ def fun(x: a): pass
def cmp(o1, o2): def cmp(o1, o2):
return o1 == o2 return o1 == o2
with infinite_recursion(25): # magic number, small but reasonable with infinite_recursion():
r1 = namespace1() r1 = namespace1()
r2 = namespace2() r2 = namespace2()
self.assertIsNot(r1, r2) self.assertIsNot(r1, r2)

View file

@ -0,0 +1,4 @@
Make the default value of ``test.support.infinite_recursion()`` to be
conditional based on whether optimizations were used when compiling the
interpreter. This helps with platforms like WASI whose stack size is greatly
restricted in debug builds.