diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index bb282eba5d41eec..b1483ad6bf2d401 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -1107,13 +1107,11 @@ def next(self): enum._test_simple_enum(_Precedence, _ast_unparse._Precedence) @support.cpython_only - @support.run_with_limited_c_stack( - 100_000 if sys.platform == "android" else 500_000) + @support.run_with_limited_c_stack(500_000) @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_ast_recursion_limit(self): - # Android test devices have less memory. - crash_depth = 100_000 if sys.platform == "android" else 500_000 + crash_depth = 500_000 success_depth = 200 if _testinternalcapi is not None: remaining = _testinternalcapi.get_c_recursion_remaining() diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 53b4be1e75b65a1..60886b1a55c16f4 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -773,14 +773,12 @@ def test_yet_more_evil_still_undecodable(self): @support.cpython_only @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") - @support.run_with_limited_c_stack( - 100_000 if sys.platform == "android" else 500_000) + @support.run_with_limited_c_stack(500_000) @support.skip_emscripten_stack_overflow() def test_compiler_recursion_limit(self): # Compiler frames are small limit = 100 - # Android test devices have less memory. - crash_depth = limit * (1000 if sys.platform == "android" else 5000) + crash_depth = limit * 5000 success_depth = limit def check_limit(prefix, repeated, mode="single"): @@ -1092,8 +1090,7 @@ def test_path_like_objects(self): # complex statements. @support.requires_resource('cpu') def test_stack_overflow(self): - # Android test devices have less memory. - size = 100_000 if sys.platform == "android" else 200_000 + size = 200_000 compile("if a: b\n" * size, "", "exec") # Multiple users rely on the fact that CPython does not generate diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-16-38-00.gh-issue-159320._Yhg1s.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-16-38-00.gh-issue-159320._Yhg1s.rst new file mode 100644 index 000000000000000..25e8745ccc02bb0 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-13-16-38-00.gh-issue-159320._Yhg1s.rst @@ -0,0 +1,2 @@ +Add dynamic detection of stack sizes on Android, allowing safer deep +recursion. diff --git a/Python/ceval.c b/Python/ceval.c index acf012c44a53050..43dc48f375301cc 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -142,11 +142,14 @@ hardware_stack_limits(uintptr_t *base, uintptr_t *top, uintptr_t sp) *top = (uintptr_t)stack_addr; *base = ((uintptr_t)stack_addr) - stack_size; #else - /// XXX musl supports HAVE_PTHRED_GETATTR_NP, but the resulting stack size - /// (on alpine at least) is much smaller than expected and imposes undue limits - /// compared to the old stack size estimation. (We assume musl is not glibc.) + // musl supports HAVE_PTHREAD_GETATTR_NP, but the resulting stack size + // (on alpine at least) is much smaller than expected and imposes undue + // limits compared to the old stack size estimation. musl doesn't give + // us a way to detect it, so we have to assume any non-glibc, + // non-Android Linux is musl and mustn't rely on pthread_getattr_np. # if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(_AIX) && \ - !defined(__NetBSD__) && (defined(__GLIBC__) || !defined(__linux__)) + !defined(__NetBSD__) && \ + (defined(__GLIBC__) || defined(__ANDROID__) || !defined(__linux__)) size_t stack_size, guard_size; void *stack_addr; pthread_attr_t attr;