From f489ace9e7aaa29b5a83b0a74a247abc8b032910 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 17 Nov 2023 15:52:11 -0800 Subject: [PATCH] GH-111808: Make the default value for `test.support.infinite_recursion()` conditional on compiler optimizations (GH-112223) Co-authored-by: Victor Stinner --- Lib/test/support/__init__.py | 12 ++++++++++-- Lib/test/test_richcmp.py | 2 +- Lib/test/test_typing.py | 2 +- .../2023-11-17-15-20-41.gh-issue-111808.jtIayt.rst | 4 ++++ 4 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2023-11-17-15-20-41.gh-issue-111808.jtIayt.rst diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index d476ba50df1..bb9f998db46 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2120,13 +2120,21 @@ def set_recursion_limit(limit): finally: 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 (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.""" - 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}") depth = get_recursion_depth() depth = max(depth - 1, 1) # Ignore infinite_recursion() frame. diff --git a/Lib/test/test_richcmp.py b/Lib/test/test_richcmp.py index 5f449cdc05c..6fb31c80d7e 100644 --- a/Lib/test/test_richcmp.py +++ b/Lib/test/test_richcmp.py @@ -221,7 +221,7 @@ class MiscTest(unittest.TestCase): self.assertRaises(Exc, func, Bad()) @support.no_tracing - @support.infinite_recursion(25) + @support.infinite_recursion() def test_recursion(self): # Check that comparison for recursive objects fails gracefully from collections import UserList diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 8681e7efba3..2b5f34b4b92 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -5621,7 +5621,7 @@ class ForwardRefTests(BaseTestCase): def cmp(o1, o2): return o1 == o2 - with infinite_recursion(25): # magic number, small but reasonable + with infinite_recursion(): r1 = namespace1() r2 = namespace2() self.assertIsNot(r1, r2) diff --git a/Misc/NEWS.d/next/Tests/2023-11-17-15-20-41.gh-issue-111808.jtIayt.rst b/Misc/NEWS.d/next/Tests/2023-11-17-15-20-41.gh-issue-111808.jtIayt.rst new file mode 100644 index 00000000000..36151d4b0ad --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2023-11-17-15-20-41.gh-issue-111808.jtIayt.rst @@ -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.