From d50ba27478e7f898622088cc2455a38aa592101d Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 24 Feb 2025 10:47:08 +0000 Subject: [PATCH 01/21] Revert "GH-91079: Revert "GH-91079: Implement C stack limits using addresses, not counters. (GH-130007)" for now (GH130413)" This reverts commit ef29104f7d7ad7864f5f153cd7391af73d7cef63. --- Doc/c-api/exceptions.rst | 6 +- Include/cpython/object.h | 11 +- Include/cpython/pystate.h | 34 +- Include/internal/pycore_ceval.h | 41 +- Include/internal/pycore_symtable.h | 2 - Include/internal/pycore_tstate.h | 5 + Include/pythonrun.h | 20 +- Lib/test/list_tests.py | 6 +- Lib/test/mapping_tests.py | 7 +- Lib/test/pythoninfo.py | 1 - Lib/test/support/__init__.py | 16 +- Lib/test/test_ast/test_ast.py | 23 +- Lib/test/test_call.py | 6 +- Lib/test/test_capi/test_misc.py | 2 +- Lib/test/test_compile.py | 14 +- Lib/test/test_dict.py | 5 +- Lib/test/test_dictviews.py | 5 +- Lib/test/test_exception_group.py | 4 +- Lib/test/test_exceptions.py | 2 +- Lib/test/test_fstring.py | 25 +- Lib/test/test_functools.py | 7 +- Lib/test/test_isinstance.py | 11 +- Lib/test/test_json/test_recursion.py | 1 + Lib/test/test_marshal.py | 3 +- Lib/test/test_sys_settrace.py | 6 +- Lib/test/test_tokenize.py | 1 + Lib/test/test_userdict.py | 6 +- Lib/test/test_userlist.py | 4 +- Lib/test/test_xml_etree_c.py | 1 + ...5-02-12-12-44-36.gh-issue-91079.8Nq08d.rst | 3 + Modules/_testcapimodule.c | 1 - Modules/_testinternalcapi.c | 6 +- Objects/object.c | 31 +- Parser/asdl_c.py | 63 +- Parser/parser.c | 878 +++++++++--------- Python/Python-ast.c | 733 +++++++-------- Python/ast.c | 392 ++++---- Python/ast_opt.c | 56 +- Python/bytecodes.c | 11 +- Python/ceval.c | 122 ++- Python/executor_cases.c.h | 9 +- Python/generated_cases.c.h | 11 +- Python/pystate.c | 11 +- Python/pythonrun.c | 27 +- Python/symtable.c | 47 +- Tools/cases_generator/analyzer.py | 2 +- Tools/peg_generator/pegen/c_generator.py | 4 +- 47 files changed, 1218 insertions(+), 1464 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-02-12-12-44-36.gh-issue-91079.8Nq08d.rst diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index c1f0bd750361d6..19f6baf9b3dc90 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -921,11 +921,7 @@ because the :ref:`call protocol ` takes care of recursion handling. Marks a point where a recursive C-level call is about to be performed. - If :c:macro:`!USE_STACKCHECK` is defined, this function checks if the OS - stack overflowed using :c:func:`PyOS_CheckStack`. If this is the case, it - sets a :exc:`MemoryError` and returns a nonzero value. - - The function then checks if the recursion limit is reached. If this is the + The function then checks if the stack limit is reached. If this is the case, a :exc:`RecursionError` is set and a nonzero value is returned. Otherwise, zero is returned. diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 71bd01884426ad..260b90da24c18b 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -487,18 +487,19 @@ PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(PyThreadState *tstate); * we have headroom above the trigger limit */ #define Py_TRASHCAN_HEADROOM 50 +/* Helper function for Py_TRASHCAN_BEGIN */ +PyAPI_FUNC(int) _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count); + #define Py_TRASHCAN_BEGIN(op, dealloc) \ do { \ PyThreadState *tstate = PyThreadState_Get(); \ - if (tstate->c_recursion_remaining <= Py_TRASHCAN_HEADROOM && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \ + if (_Py_ReachedRecursionLimitWithMargin(tstate, 1) && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \ _PyTrash_thread_deposit_object(tstate, (PyObject *)op); \ break; \ - } \ - tstate->c_recursion_remaining--; + } /* The body of the deallocator is here. */ #define Py_TRASHCAN_END \ - tstate->c_recursion_remaining++; \ - if (tstate->delete_later && tstate->c_recursion_remaining > (Py_TRASHCAN_HEADROOM*2)) { \ + if (tstate->delete_later && !_Py_ReachedRecursionLimitWithMargin(tstate, 2)) { \ _PyTrash_thread_destroy_chain(tstate); \ } \ } while (0); diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index cd6d9582496850..e0d2ac9bf93ad8 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -112,7 +112,7 @@ struct _ts { int py_recursion_remaining; int py_recursion_limit; - int c_recursion_remaining; + int c_recursion_remaining; /* Retained for backwards compatibility. Do not use */ int recursion_headroom; /* Allow 50 more calls to handle any errors. */ /* 'tracing' keeps track of the execution depth when tracing/profiling. @@ -202,36 +202,7 @@ struct _ts { PyObject *threading_local_sentinel; }; -#ifdef Py_DEBUG - // A debug build is likely built with low optimization level which implies - // higher stack memory usage than a release build: use a lower limit. -# define Py_C_RECURSION_LIMIT 500 -#elif defined(__s390x__) -# define Py_C_RECURSION_LIMIT 800 -#elif defined(_WIN32) && defined(_M_ARM64) -# define Py_C_RECURSION_LIMIT 1000 -#elif defined(_WIN32) -# define Py_C_RECURSION_LIMIT 3000 -#elif defined(__ANDROID__) - // On an ARM64 emulator, API level 34 was OK with 10000, but API level 21 - // crashed in test_compiler_recursion_limit. -# define Py_C_RECURSION_LIMIT 3000 -#elif defined(_Py_ADDRESS_SANITIZER) -# define Py_C_RECURSION_LIMIT 4000 -#elif defined(__sparc__) - // test_descr crashed on sparc64 with >7000 but let's keep a margin of error. -# define Py_C_RECURSION_LIMIT 4000 -#elif defined(__wasi__) - // Based on wasmtime 16. -# define Py_C_RECURSION_LIMIT 5000 -#elif defined(__hppa__) || defined(__powerpc64__) - // test_descr crashed with >8000 but let's keep a margin of error. -# define Py_C_RECURSION_LIMIT 5000 -#else - // This value is duplicated in Lib/test/support/__init__.py -# define Py_C_RECURSION_LIMIT 10000 -#endif - +# define Py_C_RECURSION_LIMIT 5000 /* other API */ @@ -246,7 +217,6 @@ _PyThreadState_UncheckedGet(void) return PyThreadState_GetUnchecked(); } - // Disable tracing and profiling. PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate); diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 6265afba38be26..f9e6a99ce29d2b 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -193,18 +193,12 @@ extern void _PyEval_DeactivateOpCache(void); /* --- _Py_EnterRecursiveCall() ----------------------------------------- */ -#ifdef USE_STACKCHECK -/* With USE_STACKCHECK macro defined, trigger stack checks in - _Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */ static inline int _Py_MakeRecCheck(PyThreadState *tstate) { - return (tstate->c_recursion_remaining-- < 0 - || (tstate->c_recursion_remaining & 63) == 0); + char here; + uintptr_t here_addr = (uintptr_t)&here; + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + return here_addr < _tstate->c_stack_soft_limit; } -#else -static inline int _Py_MakeRecCheck(PyThreadState *tstate) { - return tstate->c_recursion_remaining-- < 0; -} -#endif // Export for '_json' shared extension, used via _Py_EnterRecursiveCall() // static inline function. @@ -220,23 +214,31 @@ static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate, return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where)); } -static inline void _Py_EnterRecursiveCallTstateUnchecked(PyThreadState *tstate) { - assert(tstate->c_recursion_remaining > 0); - tstate->c_recursion_remaining--; -} - static inline int _Py_EnterRecursiveCall(const char *where) { PyThreadState *tstate = _PyThreadState_GET(); return _Py_EnterRecursiveCallTstate(tstate, where); } -static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { - tstate->c_recursion_remaining++; +static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { + (void)tstate; +} + +PyAPI_FUNC(void) _Py_InitializeRecursionLimits(PyThreadState *tstate); + +static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate) { + char here; + uintptr_t here_addr = (uintptr_t)&here; + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + if (here_addr > _tstate->c_stack_soft_limit) { + return 0; + } + if (_tstate->c_stack_hard_limit == 0) { + _Py_InitializeRecursionLimits(tstate); + } + return here_addr <= _tstate->c_stack_soft_limit; } static inline void _Py_LeaveRecursiveCall(void) { - PyThreadState *tstate = _PyThreadState_GET(); - _Py_LeaveRecursiveCallTstate(tstate); } extern struct _PyInterpreterFrame* _PyEval_GetFrame(void); @@ -327,7 +329,6 @@ void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit); PyAPI_FUNC(PyObject *) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value); - #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h index b7e274296112aa..3b87a7f869c4d7 100644 --- a/Include/internal/pycore_symtable.h +++ b/Include/internal/pycore_symtable.h @@ -82,8 +82,6 @@ struct symtable { PyObject *st_private; /* name of current class or NULL */ _PyFutureFeatures *st_future; /* module's future features that affect the symbol table */ - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ }; typedef struct _symtable_entry { diff --git a/Include/internal/pycore_tstate.h b/Include/internal/pycore_tstate.h index 932623f54c4260..624b29e32ed463 100644 --- a/Include/internal/pycore_tstate.h +++ b/Include/internal/pycore_tstate.h @@ -21,6 +21,11 @@ typedef struct _PyThreadStateImpl { // semi-public fields are in PyThreadState. PyThreadState base; + // These are addresses, but we need to convert to ints to avoid UB. + uintptr_t c_stack_top; + uintptr_t c_stack_soft_limit; + uintptr_t c_stack_hard_limit; + PyObject *asyncio_running_loop; // Strong reference PyObject *asyncio_running_task; // Strong reference diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 154c7450cb934f..03b713beb8155f 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -21,14 +21,18 @@ PyAPI_FUNC(void) PyErr_DisplayException(PyObject *); /* Stuff with no proper home (yet) */ PyAPI_DATA(int) (*PyOS_InputHook)(void); -/* Stack size, in "pointers" (so we get extra safety margins - on 64-bit platforms). On a 32-bit platform, this translates - to an 8k margin. */ -#define PYOS_STACK_MARGIN 2048 - -#if defined(WIN32) && !defined(MS_WIN64) && !defined(_M_ARM) && defined(_MSC_VER) && _MSC_VER >= 1300 -/* Enable stack checking under Microsoft C */ -// When changing the platforms, ensure PyOS_CheckStack() docs are still correct +/* Stack size, in "pointers". This must be large enough, so + * no two calls to check recursion depth are more than this far + * apart. In practice, that means it must be larger than the C + * stack consumption of PyEval_EvalDefault */ +#if defined(Py_DEBUG) && defined(WIN32) +# define PYOS_STACK_MARGIN 3072 +#else +# define PYOS_STACK_MARGIN 2048 +#endif +#define PYOS_STACK_MARGIN_BYTES (PYOS_STACK_MARGIN * sizeof(void *)) + +#if defined(WIN32) #define USE_STACKCHECK #endif diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index dbd9f27872962d..4e63abfc3ce1b3 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -6,7 +6,8 @@ from functools import cmp_to_key from test import seq_tests -from test.support import ALWAYS_EQ, NEVER_EQ, get_c_recursion_limit, skip_emscripten_stack_overflow +from test.support import ALWAYS_EQ, NEVER_EQ +from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow class CommonTest(seq_tests.CommonTest): @@ -59,10 +60,11 @@ def test_repr(self): self.assertEqual(str(a2), "[0, 1, 2, [...], 3]") self.assertEqual(repr(a2), "[0, 1, 2, [...], 3]") + @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_repr_deep(self): a = self.type2test([]) - for i in range(get_c_recursion_limit() + 1): + for i in range(100_000): a = self.type2test([a]) self.assertRaises(RecursionError, repr, a) diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index f249f0021e9c1c..1a0caa00fcd49e 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -1,7 +1,7 @@ # tests common to dict and UserDict import unittest import collections -from test.support import get_c_recursion_limit, skip_emscripten_stack_overflow +from test import support class BasicTestMappingProtocol(unittest.TestCase): @@ -622,10 +622,11 @@ def __repr__(self): d = self._full_mapping({1: BadRepr()}) self.assertRaises(Exc, repr, d) - @skip_emscripten_stack_overflow() + @support.skip_wasi_stack_overflow() + @support.skip_emscripten_stack_overflow() def test_repr_deep(self): d = self._empty_mapping() - for i in range(get_c_recursion_limit() + 1): + for i in range(support.exceeds_recursion_limit()): d0 = d d = self._empty_mapping() d[1] = d0 diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 0b2e4b1c1988c4..38236d82376f37 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -684,7 +684,6 @@ def collect_testcapi(info_add): for name in ( 'LONG_MAX', # always 32-bit on Windows, 64-bit on 64-bit Unix 'PY_SSIZE_T_MAX', - 'Py_C_RECURSION_LIMIT', 'SIZEOF_TIME_T', # 32-bit or 64-bit depending on the platform 'SIZEOF_WCHAR_T', # 16-bit or 32-bit depending on the platform ): diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index f31d98bf731d67..88ac5a56ee928e 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -56,8 +56,7 @@ "run_with_tz", "PGO", "missing_compiler_executable", "ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST", "LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT", - "Py_DEBUG", "exceeds_recursion_limit", "get_c_recursion_limit", - "skip_on_s390x", + "Py_DEBUG", "exceeds_recursion_limit", "skip_on_s390x", "requires_jit_enabled", "requires_jit_disabled", "force_not_colorized", @@ -558,6 +557,9 @@ def skip_android_selinux(name): def skip_emscripten_stack_overflow(): return unittest.skipIf(is_emscripten, "Exhausts limited stack on Emscripten") +def skip_wasi_stack_overflow(): + return unittest.skipIf(is_wasi, "Exhausts stack on WASI") + is_apple_mobile = sys.platform in {"ios", "tvos", "watchos"} is_apple = is_apple_mobile or sys.platform == "darwin" @@ -2624,17 +2626,9 @@ def adjust_int_max_str_digits(max_digits): sys.set_int_max_str_digits(current) -def get_c_recursion_limit(): - try: - import _testcapi - return _testcapi.Py_C_RECURSION_LIMIT - except ImportError: - raise unittest.SkipTest('requires _testcapi') - - def exceeds_recursion_limit(): """For recursion tests, easily exceeds default recursion limit.""" - return get_c_recursion_limit() * 3 + return 100_000 # Windows doesn't have os.uname() but it doesn't support s390x. diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 80c9f69ba77840..1c202f82e941e8 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -18,7 +18,8 @@ _testinternalcapi = None from test import support -from test.support import os_helper, script_helper, skip_emscripten_stack_overflow +from test.support import os_helper, script_helper +from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow from test.support.ast_helper import ASTTestMixin from test.test_ast.utils import to_tuple from test.test_ast.snippets import ( @@ -750,11 +751,11 @@ def next(self): enum._test_simple_enum(_Precedence, ast._Precedence) @support.cpython_only + @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_ast_recursion_limit(self): - fail_depth = support.exceeds_recursion_limit() - crash_depth = 100_000 - success_depth = int(support.get_c_recursion_limit() * 0.8) + crash_depth = 200_000 + success_depth = 200 if _testinternalcapi is not None: remaining = _testinternalcapi.get_c_recursion_remaining() success_depth = min(success_depth, remaining) @@ -762,13 +763,13 @@ def test_ast_recursion_limit(self): def check_limit(prefix, repeated): expect_ok = prefix + repeated * success_depth ast.parse(expect_ok) - for depth in (fail_depth, crash_depth): - broken = prefix + repeated * depth - details = "Compiling ({!r} + {!r} * {})".format( - prefix, repeated, depth) - with self.assertRaises(RecursionError, msg=details): - with support.infinite_recursion(): - ast.parse(broken) + + broken = prefix + repeated * crash_depth + details = "Compiling ({!r} + {!r} * {})".format( + prefix, repeated, crash_depth) + with self.assertRaises(RecursionError, msg=details): + with support.infinite_recursion(): + ast.parse(broken) check_limit("a", "()") check_limit("a", ".b") diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 9d73d0e690ed58..95eaf810eea091 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -1,6 +1,6 @@ import unittest from test.support import (cpython_only, is_wasi, requires_limited_api, Py_DEBUG, - set_recursion_limit, skip_on_s390x, skip_emscripten_stack_overflow, + set_recursion_limit, skip_on_s390x, exceeds_recursion_limit, skip_emscripten_stack_overflow, skip_if_sanitizer, import_helper) try: import _testcapi @@ -1064,10 +1064,10 @@ def c_py_recurse(m): recurse(90_000) with self.assertRaises(RecursionError): recurse(101_000) - c_recurse(100) + c_recurse(50) with self.assertRaises(RecursionError): c_recurse(90_000) - c_py_recurse(90) + c_py_recurse(50) with self.assertRaises(RecursionError): c_py_recurse(100_000) diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index b218f72f1bbce0..6c4cf5bd6598bc 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -408,7 +408,7 @@ def test_trashcan_subclass(self): # activated when its tp_dealloc is being called by a subclass from _testcapi import MyList L = None - for i in range(1000): + for i in range(100): L = MyList((L,)) @support.requires_resource('cpu') diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 8163b483d9603d..e0a33b8141c709 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -21,7 +21,7 @@ from test import support from test.support import (script_helper, requires_debug_ranges, run_code, - requires_specialization, get_c_recursion_limit) + requires_specialization) from test.support.bytecode_helper import instructions_with_positions from test.support.os_helper import FakePath @@ -123,7 +123,7 @@ def __getitem__(self, key): @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") @support.skip_emscripten_stack_overflow() def test_extended_arg(self): - repeat = int(get_c_recursion_limit() * 0.9) + repeat = 100 longexpr = 'x = x or ' + '-x' * repeat g = {} code = textwrap.dedent(''' @@ -712,11 +712,11 @@ def test_yet_more_evil_still_undecodable(self): @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") @support.skip_emscripten_stack_overflow() def test_compiler_recursion_limit(self): - # Expected limit is Py_C_RECURSION_LIMIT - limit = get_c_recursion_limit() - fail_depth = limit + 1 - crash_depth = limit * 100 - success_depth = int(limit * 0.8) + # Compiler frames are small + limit = 100 + fail_depth = limit * 1000 + crash_depth = limit * 2000 + success_depth = limit def check_limit(prefix, repeated, mode="single"): expect_ok = prefix + repeated * success_depth diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 86b2f22dee5347..7756c1f995cf2c 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -8,7 +8,7 @@ import unittest import weakref from test import support -from test.support import import_helper, get_c_recursion_limit +from test.support import import_helper class DictTest(unittest.TestCase): @@ -594,10 +594,11 @@ def __repr__(self): d = {1: BadRepr()} self.assertRaises(Exc, repr, d) + @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() def test_repr_deep(self): d = {} - for i in range(get_c_recursion_limit() + 1): + for i in range(support.exceeds_recursion_limit()): d = {1: d} self.assertRaises(RecursionError, repr, d) diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index d6bf00eeeb0013..691fc5dfb5e8ab 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -2,7 +2,7 @@ import copy import pickle import unittest -from test.support import get_c_recursion_limit, skip_emscripten_stack_overflow +from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow, exceeds_recursion_limit class DictSetTest(unittest.TestCase): @@ -277,10 +277,11 @@ def test_recursive_repr(self): # Again. self.assertIsInstance(r, str) + @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_deeply_nested_repr(self): d = {} - for i in range(get_c_recursion_limit()//2 + 100): + for i in range(exceeds_recursion_limit()): d = {42: d.values()} self.assertRaises(RecursionError, repr, d) diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index 53212529c27e28..92bbf7917642b0 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -1,7 +1,7 @@ import collections.abc import types import unittest -from test.support import get_c_recursion_limit, skip_emscripten_stack_overflow +from test.support import skip_emscripten_stack_overflow, exceeds_recursion_limit class TestExceptionGroupTypeHierarchy(unittest.TestCase): def test_exception_group_types(self): @@ -460,7 +460,7 @@ def test_basics_split_by_predicate__match(self): class DeepRecursionInSplitAndSubgroup(unittest.TestCase): def make_deep_eg(self): e = TypeError(1) - for i in range(get_c_recursion_limit() + 1): + for i in range(exceeds_recursion_limit()): e = ExceptionGroup('eg', [e]) return e diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 7aa200ad8bee6c..bd1053b67fde58 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1479,7 +1479,7 @@ def test_recursion_normalizing_infinite_exception(self): """ rc, out, err = script_helper.assert_python_failure("-c", code) self.assertEqual(rc, 1) - expected = b'RecursionError: maximum recursion depth exceeded' + expected = b'RecursionError' self.assertTrue(expected in err, msg=f"{expected!r} not found in {err[:3_000]!r}... (truncated)") self.assertIn(b'Done.', out) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index f5111b38a45707..5974024c170cef 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -628,13 +628,23 @@ def test_mismatched_parens(self): r"does not match opening parenthesis '\('", ["f'{a(4}'", ]) - self.assertRaises(SyntaxError, eval, "f'{" + "("*500 + "}'") + self.assertRaises(SyntaxError, eval, "f'{" + "("*20 + "}'") @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_fstring_nested_too_deeply(self): - self.assertAllRaise(SyntaxError, - "f-string: expressions nested too deeply", - ['f"{1+2:{1+2:{1+1:{1}}}}"']) + def raises_syntax_or_memory_error(txt): + try: + eval(txt) + except SyntaxError: + pass + except MemoryError: + pass + except Exception as ex: + self.fail(f"Should raise SyntaxError or MemoryError, not {type(ex)}") + else: + self.fail("No exception raised") + + raises_syntax_or_memory_error('f"{1+2:{1+2:{1+1:{1}}}}"') def create_nested_fstring(n): if n == 0: @@ -642,9 +652,10 @@ def create_nested_fstring(n): prev = create_nested_fstring(n-1) return f'f"{{{prev}}}"' - self.assertAllRaise(SyntaxError, - "too many nested f-strings", - [create_nested_fstring(160)]) + raises_syntax_or_memory_error(create_nested_fstring(160)) + raises_syntax_or_memory_error("f'{" + "("*100 + "}'") + raises_syntax_or_memory_error("f'{" + "("*1000 + "}'") + raises_syntax_or_memory_error("f'{" + "("*10_000 + "}'") def test_syntax_error_in_nested_fstring(self): # See gh-104016 for more information on this crash diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 4ebe1c4615b7e3..b272631ae72c9d 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -2087,15 +2087,12 @@ def fib(n): return n return fib(n-1) + fib(n-2) - if not support.Py_DEBUG: - depth = support.get_c_recursion_limit()*2//7 - with support.infinite_recursion(): - fib(depth) + fib(100) if self.module == c_functools: fib.cache_clear() with support.infinite_recursion(): with self.assertRaises(RecursionError): - fib(10000) + fib(support.exceeds_recursion_limit()) @py_functools.lru_cache() diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index abc75c82375d98..115e26c5541526 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -267,15 +267,13 @@ def test_subclass_tuple(self): def test_subclass_recursion_limit(self): # make sure that issubclass raises RecursionError before the C stack is # blown - with support.infinite_recursion(): - self.assertRaises(RecursionError, blowstack, issubclass, str, str) + self.assertRaises(RecursionError, blowstack, issubclass, str, str) @support.skip_emscripten_stack_overflow() def test_isinstance_recursion_limit(self): # make sure that issubclass raises RecursionError before the C stack is # blown - with support.infinite_recursion(): - self.assertRaises(RecursionError, blowstack, isinstance, '', str) + self.assertRaises(RecursionError, blowstack, isinstance, '', str) def test_subclass_with_union(self): self.assertTrue(issubclass(int, int | float | int)) @@ -355,8 +353,9 @@ def blowstack(fxn, arg, compare_to): # Make sure that calling isinstance with a deeply nested tuple for its # argument will raise RecursionError eventually. tuple_arg = (compare_to,) - for cnt in range(support.exceeds_recursion_limit()): - tuple_arg = (tuple_arg,) + while True: + for _ in range(100): + tuple_arg = (tuple_arg,) fxn(arg, tuple_arg) diff --git a/Lib/test/test_json/test_recursion.py b/Lib/test/test_json/test_recursion.py index 663c0643579ac8..700821f8625834 100644 --- a/Lib/test/test_json/test_recursion.py +++ b/Lib/test/test_json/test_recursion.py @@ -82,6 +82,7 @@ def test_highly_nested_objects_decoding(self): with support.infinite_recursion(): self.loads('[' * 100000 + '1' + ']' * 100000) + @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() def test_highly_nested_objects_encoding(self): # See #12051 diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index 4ed9f1fc1b8020..8b1fb0eba1f8b6 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -125,8 +125,7 @@ def test_code(self): def test_many_codeobjects(self): # Issue2957: bad recursion count on code objects # more than MAX_MARSHAL_STACK_DEPTH - count = support.exceeds_recursion_limit() - codes = (ExceptionTestCase.test_exceptions.__code__,) * count + codes = (ExceptionTestCase.test_exceptions.__code__,) * 10_000 marshal.loads(marshal.dumps(codes)) def test_different_filenames(self): diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 28c2c681babe18..e528c6a9c69d28 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -3035,18 +3035,18 @@ def test_trace_unpack_long_sequence(self): def test_trace_lots_of_globals(self): - count = min(1000, int(support.get_c_recursion_limit() * 0.8)) + count = 1000 code = """if 1: def f(): return ( {} ) - """.format("\n+\n".join(f"var{i}\n" for i in range(count))) + """.format("\n,\n".join(f"var{i}\n" for i in range(count))) ns = {f"var{i}": i for i in range(count)} exec(code, ns) counts = self.count_traces(ns["f"]) - self.assertEqual(counts, {'call': 1, 'line': count * 2, 'return': 1}) + self.assertEqual(counts, {'call': 1, 'line': count * 2 + 1, 'return': 1}) class TestEdgeCases(unittest.TestCase): diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index 52d3341975088b..5fa4e0d922ed08 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -3040,6 +3040,7 @@ def get_tokens(string): with self.subTest(case=case): self.assertRaises(tokenize.TokenError, get_tokens, case) + @support.skip_wasi_stack_overflow() def test_max_indent(self): MAXINDENT = 100 diff --git a/Lib/test/test_userdict.py b/Lib/test/test_userdict.py index 61e79f553e8ec9..9bd842eda5b49c 100644 --- a/Lib/test/test_userdict.py +++ b/Lib/test/test_userdict.py @@ -213,11 +213,7 @@ class G(collections.UserDict): else: self.fail("g[42] didn't raise KeyError") - # Decorate existing test with recursion limit, because - # the test is for C structure, but `UserDict` is a Python structure. - test_repr_deep = support.infinite_recursion(25)( - mapping_tests.TestHashMappingProtocol.test_repr_deep, - ) + test_repr_deep = mapping_tests.TestHashMappingProtocol.test_repr_deep if __name__ == "__main__": diff --git a/Lib/test/test_userlist.py b/Lib/test/test_userlist.py index 312702c8e398b9..e82e88f3f3ed1d 100644 --- a/Lib/test/test_userlist.py +++ b/Lib/test/test_userlist.py @@ -69,9 +69,7 @@ def test_userlist_copy(self): # Decorate existing test with recursion limit, because # the test is for C structure, but `UserList` is a Python structure. - test_repr_deep = support.infinite_recursion(25)( - list_tests.CommonTest.test_repr_deep, - ) + test_repr_deep = list_tests.CommonTest.test_repr_deep if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index db19af419bdeab..9ed0f4096a45e3 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -57,6 +57,7 @@ def test_del_attribute(self): del element.attrib self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + @support.skip_wasi_stack_overflow() @unittest.skipIf(support.is_emscripten, "segfaults") def test_trashcan(self): # If this test fails, it will most likely die via segfault. diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-12-12-44-36.gh-issue-91079.8Nq08d.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-12-12-44-36.gh-issue-91079.8Nq08d.rst new file mode 100644 index 00000000000000..e592a7d4d4d37a --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-12-12-44-36.gh-issue-91079.8Nq08d.rst @@ -0,0 +1,3 @@ +Change C stack overflow protection to consider the amount of stack consumed, +rather than a counter. This allows deeper recursion in many cases, but +remains safe. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 3d5fa9006447de..9260c7659440ea 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3239,7 +3239,6 @@ PyInit__testcapi(void) PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); PyModule_AddIntConstant(m, "the_number_three", 3); - PyModule_AddIntMacro(m, Py_C_RECURSION_LIMIT); PyModule_AddObject(m, "INT32_MIN", PyLong_FromInt32(INT32_MIN)); PyModule_AddObject(m, "INT32_MAX", PyLong_FromInt32(INT32_MAX)); PyModule_AddObject(m, "UINT32_MAX", PyLong_FromUInt32(UINT32_MAX)); diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index e44b629897c58a..67cd96ac55e779 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -115,7 +115,11 @@ static PyObject* get_c_recursion_remaining(PyObject *self, PyObject *Py_UNUSED(args)) { PyThreadState *tstate = _PyThreadState_GET(); - return PyLong_FromLong(tstate->c_recursion_remaining); + char here; + uintptr_t here_addr = (uintptr_t)&here; + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + int remaining = (int)((here_addr - _tstate->c_stack_soft_limit)/PYOS_STACK_MARGIN_BYTES * 50); + return PyLong_FromLong(remaining); } diff --git a/Objects/object.c b/Objects/object.c index 16aedac916bf34..d342549b6ffecc 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -612,12 +612,9 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) int write_error = 0; if (PyErr_CheckSignals()) return -1; -#ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - PyErr_SetString(PyExc_MemoryError, "stack overflow"); + if (_Py_EnterRecursiveCall(" printing an object")) { return -1; } -#endif clearerr(fp); /* Clear any previous error condition */ if (op == NULL) { Py_BEGIN_ALLOW_THREADS @@ -738,12 +735,6 @@ PyObject_Repr(PyObject *v) PyObject *res; if (PyErr_CheckSignals()) return NULL; -#ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - PyErr_SetString(PyExc_MemoryError, "stack overflow"); - return NULL; - } -#endif if (v == NULL) return PyUnicode_FromString(""); if (Py_TYPE(v)->tp_repr == NULL) @@ -786,12 +777,6 @@ PyObject_Str(PyObject *v) PyObject *res; if (PyErr_CheckSignals()) return NULL; -#ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - PyErr_SetString(PyExc_MemoryError, "stack overflow"); - return NULL; - } -#endif if (v == NULL) return PyUnicode_FromString(""); if (PyUnicode_CheckExact(v)) { @@ -2900,19 +2885,6 @@ _PyTrash_thread_deposit_object(PyThreadState *tstate, PyObject *op) void _PyTrash_thread_destroy_chain(PyThreadState *tstate) { - /* We need to increase c_recursion_remaining here, otherwise, - _PyTrash_thread_destroy_chain will be called recursively - and then possibly crash. An example that may crash without - increase: - N = 500000 # need to be large enough - ob = object() - tups = [(ob,) for i in range(N)] - for i in range(49): - tups = [(tup,) for tup in tups] - del tups - */ - assert(tstate->c_recursion_remaining > Py_TRASHCAN_HEADROOM); - tstate->c_recursion_remaining--; while (tstate->delete_later) { PyObject *op = tstate->delete_later; destructor dealloc = Py_TYPE(op)->tp_dealloc; @@ -2934,7 +2906,6 @@ _PyTrash_thread_destroy_chain(PyThreadState *tstate) _PyObject_ASSERT(op, Py_REFCNT(op) == 0); (*dealloc)(op); } - tstate->c_recursion_remaining++; } void _Py_NO_RETURN diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index b2a5dd6792dead..5c8014a47d5177 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -738,7 +738,7 @@ def emit_sequence_constructor(self, name, type): class PyTypesDeclareVisitor(PickleVisitor): def visitProduct(self, prod, name): - self.emit("static PyObject* ast2obj_%s(struct ast_state *state, struct validator *vstate, void*);" % name, 0) + self.emit("static PyObject* ast2obj_%s(struct ast_state *state, void*);" % name, 0) if prod.attributes: self.emit("static const char * const %s_attributes[] = {" % name, 0) for a in prod.attributes: @@ -759,7 +759,7 @@ def visitSum(self, sum, name): ptype = "void*" if is_simple(sum): ptype = get_c_type(name) - self.emit("static PyObject* ast2obj_%s(struct ast_state *state, struct validator *vstate, %s);" % (name, ptype), 0) + self.emit("static PyObject* ast2obj_%s(struct ast_state *state, %s);" % (name, ptype), 0) for t in sum.types: self.visitConstructor(t, name) @@ -1734,8 +1734,8 @@ def visitModule(self, mod): /* Conversion AST -> Python */ -static PyObject* ast2obj_list(struct ast_state *state, struct validator *vstate, asdl_seq *seq, - PyObject* (*func)(struct ast_state *state, struct validator *vstate, void*)) +static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, + PyObject* (*func)(struct ast_state *state, void*)) { Py_ssize_t i, n = asdl_seq_LEN(seq); PyObject *result = PyList_New(n); @@ -1743,7 +1743,7 @@ def visitModule(self, mod): if (!result) return NULL; for (i = 0; i < n; i++) { - value = func(state, vstate, asdl_seq_GET_UNTYPED(seq, i)); + value = func(state, asdl_seq_GET_UNTYPED(seq, i)); if (!value) { Py_DECREF(result); return NULL; @@ -1753,7 +1753,7 @@ def visitModule(self, mod): return result; } -static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), struct validator *Py_UNUSED(vstate), void *o) +static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o) { PyObject *op = (PyObject*)o; if (!op) { @@ -1765,7 +1765,7 @@ def visitModule(self, mod): #define ast2obj_identifier ast2obj_object #define ast2obj_string ast2obj_object -static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), struct validator *Py_UNUSED(vstate), long b) +static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), long b) { return PyLong_FromLong(b); } @@ -2014,7 +2014,7 @@ class ObjVisitor(PickleVisitor): def func_begin(self, name): ctype = get_c_type(name) self.emit("PyObject*", 0) - self.emit("ast2obj_%s(struct ast_state *state, struct validator *vstate, void* _o)" % (name), 0) + self.emit("ast2obj_%s(struct ast_state *state, void* _o)" % (name), 0) self.emit("{", 0) self.emit("%s o = (%s)_o;" % (ctype, ctype), 1) self.emit("PyObject *result = NULL, *value = NULL;", 1) @@ -2022,17 +2022,15 @@ def func_begin(self, name): self.emit('if (!o) {', 1) self.emit("Py_RETURN_NONE;", 2) self.emit("}", 1) - self.emit("if (++vstate->recursion_depth > vstate->recursion_limit) {", 1) - self.emit("PyErr_SetString(PyExc_RecursionError,", 2) - self.emit('"maximum recursion depth exceeded during ast construction");', 3) + self.emit('if (Py_EnterRecursiveCall("during ast construction")) {', 1) self.emit("return NULL;", 2) self.emit("}", 1) def func_end(self): - self.emit("vstate->recursion_depth--;", 1) + self.emit("Py_LeaveRecursiveCall();", 1) self.emit("return result;", 1) self.emit("failed:", 0) - self.emit("vstate->recursion_depth--;", 1) + self.emit("Py_LeaveRecursiveCall();", 1) self.emit("Py_XDECREF(value);", 1) self.emit("Py_XDECREF(result);", 1) self.emit("return NULL;", 1) @@ -2050,7 +2048,7 @@ def visitSum(self, sum, name): self.visitConstructor(t, i + 1, name) self.emit("}", 1) for a in sum.attributes: - self.emit("value = ast2obj_%s(state, vstate, o->%s);" % (a.type, a.name), 1) + self.emit("value = ast2obj_%s(state, o->%s);" % (a.type, a.name), 1) self.emit("if (!value) goto failed;", 1) self.emit('if (PyObject_SetAttr(result, state->%s, value) < 0)' % a.name, 1) self.emit('goto failed;', 2) @@ -2058,7 +2056,7 @@ def visitSum(self, sum, name): self.func_end() def simpleSum(self, sum, name): - self.emit("PyObject* ast2obj_%s(struct ast_state *state, struct validator *vstate, %s_ty o)" % (name, name), 0) + self.emit("PyObject* ast2obj_%s(struct ast_state *state, %s_ty o)" % (name, name), 0) self.emit("{", 0) self.emit("switch(o) {", 1) for t in sum.types: @@ -2076,7 +2074,7 @@ def visitProduct(self, prod, name): for field in prod.fields: self.visitField(field, name, 1, True) for a in prod.attributes: - self.emit("value = ast2obj_%s(state, vstate, o->%s);" % (a.type, a.name), 1) + self.emit("value = ast2obj_%s(state, o->%s);" % (a.type, a.name), 1) self.emit("if (!value) goto failed;", 1) self.emit("if (PyObject_SetAttr(result, state->%s, value) < 0)" % a.name, 1) self.emit('goto failed;', 2) @@ -2117,7 +2115,7 @@ def set(self, field, value, depth): self.emit("for(i = 0; i < n; i++)", depth+1) # This cannot fail, so no need for error handling self.emit( - "PyList_SET_ITEM(value, i, ast2obj_{0}(state, vstate, ({0}_ty)asdl_seq_GET({1}, i)));".format( + "PyList_SET_ITEM(value, i, ast2obj_{0}(state, ({0}_ty)asdl_seq_GET({1}, i)));".format( field.type, value ), @@ -2126,9 +2124,9 @@ def set(self, field, value, depth): ) self.emit("}", depth) else: - self.emit("value = ast2obj_list(state, vstate, (asdl_seq*)%s, ast2obj_%s);" % (value, field.type), depth) + self.emit("value = ast2obj_list(state, (asdl_seq*)%s, ast2obj_%s);" % (value, field.type), depth) else: - self.emit("value = ast2obj_%s(state, vstate, %s);" % (field.type, value), depth, reflow=False) + self.emit("value = ast2obj_%s(state, %s);" % (field.type, value), depth, reflow=False) class PartingShots(StaticVisitor): @@ -2140,28 +2138,8 @@ class PartingShots(StaticVisitor): if (state == NULL) { return NULL; } + PyObject *result = ast2obj_mod(state, t); - int starting_recursion_depth; - /* Be careful here to prevent overflow. */ - PyThreadState *tstate = _PyThreadState_GET(); - if (!tstate) { - return NULL; - } - struct validator vstate; - vstate.recursion_limit = Py_C_RECURSION_LIMIT; - int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; - starting_recursion_depth = recursion_depth; - vstate.recursion_depth = starting_recursion_depth; - - PyObject *result = ast2obj_mod(state, &vstate, t); - - /* Check that the recursion depth counting balanced correctly */ - if (result && vstate.recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "AST constructor recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, vstate.recursion_depth); - return NULL; - } return result; } @@ -2305,11 +2283,6 @@ def generate_module_def(mod, metadata, f, internal_h): #include "structmember.h" #include - struct validator { - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ - }; - // Forward declaration static int init_types(void *arg); diff --git a/Parser/parser.c b/Parser/parser.c index 48508b14ee8716..edebddc95f968e 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -14,7 +14,7 @@ # define MAXSTACK 4000 # endif #else -# define MAXSTACK 6000 +# define MAXSTACK 4000 #endif static const int n_keyword_lists = 9; static KeywordToken *reserved_keywords[] = { @@ -947,7 +947,7 @@ static void *_tmp_172_rule(Parser *p); static mod_ty file_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -993,7 +993,7 @@ file_rule(Parser *p) static mod_ty interactive_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1036,7 +1036,7 @@ interactive_rule(Parser *p) static mod_ty eval_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1085,7 +1085,7 @@ eval_rule(Parser *p) static mod_ty func_type_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1146,7 +1146,7 @@ func_type_rule(Parser *p) static asdl_stmt_seq* statements_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1189,7 +1189,7 @@ statements_rule(Parser *p) static asdl_stmt_seq* statement_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1256,7 +1256,7 @@ statement_rule(Parser *p) static asdl_stmt_seq* statement_newline_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1387,7 +1387,7 @@ statement_newline_rule(Parser *p) static asdl_stmt_seq* simple_stmts_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1480,7 +1480,7 @@ simple_stmts_rule(Parser *p) static stmt_ty simple_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -1825,7 +1825,7 @@ simple_stmt_rule(Parser *p) static stmt_ty compound_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2015,7 +2015,7 @@ compound_stmt_rule(Parser *p) static stmt_ty assignment_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2233,7 +2233,7 @@ assignment_rule(Parser *p) static expr_ty annotated_rhs_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2303,7 +2303,7 @@ annotated_rhs_rule(Parser *p) static AugOperator* augassign_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2634,7 +2634,7 @@ augassign_rule(Parser *p) static stmt_ty return_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2698,7 +2698,7 @@ return_stmt_rule(Parser *p) static stmt_ty raise_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2798,7 +2798,7 @@ raise_stmt_rule(Parser *p) static stmt_ty pass_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2859,7 +2859,7 @@ pass_stmt_rule(Parser *p) static stmt_ty break_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2920,7 +2920,7 @@ break_stmt_rule(Parser *p) static stmt_ty continue_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -2981,7 +2981,7 @@ continue_stmt_rule(Parser *p) static stmt_ty global_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3045,7 +3045,7 @@ global_stmt_rule(Parser *p) static stmt_ty nonlocal_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3109,7 +3109,7 @@ nonlocal_stmt_rule(Parser *p) static stmt_ty del_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3194,7 +3194,7 @@ del_stmt_rule(Parser *p) static stmt_ty yield_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3255,7 +3255,7 @@ yield_stmt_rule(Parser *p) static stmt_ty assert_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3322,7 +3322,7 @@ assert_stmt_rule(Parser *p) static stmt_ty import_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3398,7 +3398,7 @@ import_stmt_rule(Parser *p) static stmt_ty import_name_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3464,7 +3464,7 @@ import_name_rule(Parser *p) static stmt_ty import_from_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3583,7 +3583,7 @@ import_from_rule(Parser *p) static asdl_alias_seq* import_from_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3718,7 +3718,7 @@ import_from_targets_rule(Parser *p) static asdl_alias_seq* import_from_as_names_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3761,7 +3761,7 @@ import_from_as_names_rule(Parser *p) static alias_ty import_from_as_name_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3825,7 +3825,7 @@ import_from_as_name_rule(Parser *p) static asdl_alias_seq* dotted_as_names_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3868,7 +3868,7 @@ dotted_as_names_rule(Parser *p) static alias_ty dotted_as_name_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -3934,7 +3934,7 @@ static expr_ty dotted_name_raw(Parser *); static expr_ty dotted_name_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -3968,7 +3968,7 @@ dotted_name_rule(Parser *p) static expr_ty dotted_name_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4036,7 +4036,7 @@ dotted_name_raw(Parser *p) static asdl_stmt_seq* block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4131,7 +4131,7 @@ block_rule(Parser *p) static asdl_expr_seq* decorators_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4174,7 +4174,7 @@ decorators_rule(Parser *p) static stmt_ty class_def_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4241,7 +4241,7 @@ class_def_rule(Parser *p) static stmt_ty class_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4336,7 +4336,7 @@ class_def_raw_rule(Parser *p) static stmt_ty function_def_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4404,7 +4404,7 @@ function_def_rule(Parser *p) static stmt_ty function_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4574,7 +4574,7 @@ function_def_raw_rule(Parser *p) static arguments_ty params_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4636,7 +4636,7 @@ params_rule(Parser *p) static arguments_ty parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4799,7 +4799,7 @@ parameters_rule(Parser *p) static asdl_arg_seq* slash_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4879,7 +4879,7 @@ slash_no_default_rule(Parser *p) static SlashWithDefault* slash_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -4968,7 +4968,7 @@ slash_with_default_rule(Parser *p) static StarEtc* star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5129,7 +5129,7 @@ star_etc_rule(Parser *p) static arg_ty kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5194,7 +5194,7 @@ kwds_rule(Parser *p) static arg_ty param_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5274,7 +5274,7 @@ param_no_default_rule(Parser *p) static arg_ty param_no_default_star_annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5352,7 +5352,7 @@ param_no_default_star_annotation_rule(Parser *p) static NameDefaultPair* param_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5438,7 +5438,7 @@ param_with_default_rule(Parser *p) static NameDefaultPair* param_maybe_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5522,7 +5522,7 @@ param_maybe_default_rule(Parser *p) static arg_ty param_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5586,7 +5586,7 @@ param_rule(Parser *p) static arg_ty param_star_annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5650,7 +5650,7 @@ param_star_annotation_rule(Parser *p) static expr_ty annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5696,7 +5696,7 @@ annotation_rule(Parser *p) static expr_ty star_annotation_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5742,7 +5742,7 @@ star_annotation_rule(Parser *p) static expr_ty default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5810,7 +5810,7 @@ default_rule(Parser *p) static stmt_ty if_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -5950,7 +5950,7 @@ if_stmt_rule(Parser *p) static stmt_ty elif_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6087,7 +6087,7 @@ elif_stmt_rule(Parser *p) static asdl_stmt_seq* else_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6155,7 +6155,7 @@ else_block_rule(Parser *p) static stmt_ty while_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6251,7 +6251,7 @@ while_stmt_rule(Parser *p) static stmt_ty for_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6448,7 +6448,7 @@ for_stmt_rule(Parser *p) static stmt_ty with_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6720,7 +6720,7 @@ with_stmt_rule(Parser *p) static withitem_ty with_item_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -6818,7 +6818,7 @@ with_item_rule(Parser *p) static stmt_ty try_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7007,7 +7007,7 @@ try_stmt_rule(Parser *p) static excepthandler_ty except_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7160,7 +7160,7 @@ except_block_rule(Parser *p) static excepthandler_ty except_star_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7274,7 +7274,7 @@ except_star_block_rule(Parser *p) static asdl_stmt_seq* finally_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7344,7 +7344,7 @@ finally_block_rule(Parser *p) static stmt_ty match_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7442,7 +7442,7 @@ match_stmt_rule(Parser *p) static expr_ty subject_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7528,7 +7528,7 @@ subject_expr_rule(Parser *p) static match_case_ty case_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7602,7 +7602,7 @@ case_block_rule(Parser *p) static expr_ty guard_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7648,7 +7648,7 @@ guard_rule(Parser *p) static pattern_ty patterns_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7728,7 +7728,7 @@ patterns_rule(Parser *p) static pattern_ty pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7785,7 +7785,7 @@ pattern_rule(Parser *p) static pattern_ty as_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7871,7 +7871,7 @@ as_pattern_rule(Parser *p) static pattern_ty or_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -7940,7 +7940,7 @@ or_pattern_rule(Parser *p) static pattern_ty closed_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8122,7 +8122,7 @@ closed_pattern_rule(Parser *p) static pattern_ty literal_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8356,7 +8356,7 @@ literal_pattern_rule(Parser *p) static expr_ty literal_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8544,7 +8544,7 @@ literal_expr_rule(Parser *p) static expr_ty complex_number_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8650,7 +8650,7 @@ complex_number_rule(Parser *p) static expr_ty signed_number_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8733,7 +8733,7 @@ signed_number_rule(Parser *p) static expr_ty signed_real_number_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8816,7 +8816,7 @@ signed_real_number_rule(Parser *p) static expr_ty real_number_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8859,7 +8859,7 @@ real_number_rule(Parser *p) static expr_ty imaginary_number_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8902,7 +8902,7 @@ imaginary_number_rule(Parser *p) static pattern_ty capture_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -8963,7 +8963,7 @@ capture_pattern_rule(Parser *p) static expr_ty pattern_capture_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9010,7 +9010,7 @@ pattern_capture_target_rule(Parser *p) static pattern_ty wildcard_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9071,7 +9071,7 @@ wildcard_pattern_rule(Parser *p) static pattern_ty value_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9136,7 +9136,7 @@ static expr_ty attr_raw(Parser *); static expr_ty attr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -9170,7 +9170,7 @@ attr_rule(Parser *p) static expr_ty attr_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9238,7 +9238,7 @@ attr_raw(Parser *p) static expr_ty name_or_attr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9295,7 +9295,7 @@ name_or_attr_rule(Parser *p) static pattern_ty group_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9344,7 +9344,7 @@ group_pattern_rule(Parser *p) static pattern_ty sequence_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9450,7 +9450,7 @@ sequence_pattern_rule(Parser *p) static asdl_seq* open_sequence_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9499,7 +9499,7 @@ open_sequence_pattern_rule(Parser *p) static asdl_seq* maybe_sequence_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9546,7 +9546,7 @@ maybe_sequence_pattern_rule(Parser *p) static pattern_ty maybe_star_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9603,7 +9603,7 @@ maybe_star_pattern_rule(Parser *p) static pattern_ty star_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9712,7 +9712,7 @@ star_pattern_rule(Parser *p) static pattern_ty mapping_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9911,7 +9911,7 @@ mapping_pattern_rule(Parser *p) static asdl_seq* items_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9949,7 +9949,7 @@ items_pattern_rule(Parser *p) static KeyPatternPair* key_value_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -9998,7 +9998,7 @@ key_value_pattern_rule(Parser *p) static expr_ty double_star_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10049,7 +10049,7 @@ double_star_pattern_rule(Parser *p) static pattern_ty class_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10279,7 +10279,7 @@ class_pattern_rule(Parser *p) static asdl_pattern_seq* positional_patterns_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10322,7 +10322,7 @@ positional_patterns_rule(Parser *p) static asdl_seq* keyword_patterns_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10360,7 +10360,7 @@ keyword_patterns_rule(Parser *p) static KeyPatternPair* keyword_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10409,7 +10409,7 @@ keyword_pattern_rule(Parser *p) static stmt_ty type_alias_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10482,7 +10482,7 @@ type_alias_rule(Parser *p) static asdl_type_param_seq* type_params_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10550,7 +10550,7 @@ type_params_rule(Parser *p) static asdl_type_param_seq* type_param_seq_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10601,7 +10601,7 @@ type_param_seq_rule(Parser *p) static type_param_ty type_param_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10770,7 +10770,7 @@ type_param_rule(Parser *p) static expr_ty type_param_bound_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10816,7 +10816,7 @@ type_param_bound_rule(Parser *p) static expr_ty type_param_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10862,7 +10862,7 @@ type_param_default_rule(Parser *p) static expr_ty type_param_starred_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -10908,7 +10908,7 @@ type_param_starred_default_rule(Parser *p) static expr_ty expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11036,7 +11036,7 @@ expressions_rule(Parser *p) static expr_ty expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11190,7 +11190,7 @@ expression_rule(Parser *p) static expr_ty yield_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11296,7 +11296,7 @@ yield_expr_rule(Parser *p) static expr_ty star_expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11419,7 +11419,7 @@ star_expressions_rule(Parser *p) static expr_ty star_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11507,7 +11507,7 @@ star_expression_rule(Parser *p) static asdl_expr_seq* star_named_expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11554,7 +11554,7 @@ star_named_expressions_rule(Parser *p) static expr_ty star_named_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11637,7 +11637,7 @@ star_named_expression_rule(Parser *p) static expr_ty assignment_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11711,7 +11711,7 @@ assignment_expression_rule(Parser *p) static expr_ty named_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11789,7 +11789,7 @@ named_expression_rule(Parser *p) static expr_ty disjunction_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11877,7 +11877,7 @@ disjunction_rule(Parser *p) static expr_ty conjunction_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -11965,7 +11965,7 @@ conjunction_rule(Parser *p) static expr_ty inversion_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12053,7 +12053,7 @@ inversion_rule(Parser *p) static expr_ty comparison_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12146,7 +12146,7 @@ comparison_rule(Parser *p) static CmpopExprPair* compare_op_bitwise_or_pair_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12355,7 +12355,7 @@ compare_op_bitwise_or_pair_rule(Parser *p) static CmpopExprPair* eq_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12401,7 +12401,7 @@ eq_bitwise_or_rule(Parser *p) static CmpopExprPair* noteq_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12447,7 +12447,7 @@ noteq_bitwise_or_rule(Parser *p) static CmpopExprPair* lte_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12493,7 +12493,7 @@ lte_bitwise_or_rule(Parser *p) static CmpopExprPair* lt_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12539,7 +12539,7 @@ lt_bitwise_or_rule(Parser *p) static CmpopExprPair* gte_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12585,7 +12585,7 @@ gte_bitwise_or_rule(Parser *p) static CmpopExprPair* gt_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12631,7 +12631,7 @@ gt_bitwise_or_rule(Parser *p) static CmpopExprPair* notin_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12680,7 +12680,7 @@ notin_bitwise_or_rule(Parser *p) static CmpopExprPair* in_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12726,7 +12726,7 @@ in_bitwise_or_rule(Parser *p) static CmpopExprPair* isnot_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12775,7 +12775,7 @@ isnot_bitwise_or_rule(Parser *p) static CmpopExprPair* is_bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12823,7 +12823,7 @@ static expr_ty bitwise_or_raw(Parser *); static expr_ty bitwise_or_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -12857,7 +12857,7 @@ bitwise_or_rule(Parser *p) static expr_ty bitwise_or_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -12945,7 +12945,7 @@ static expr_ty bitwise_xor_raw(Parser *); static expr_ty bitwise_xor_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -12979,7 +12979,7 @@ bitwise_xor_rule(Parser *p) static expr_ty bitwise_xor_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13067,7 +13067,7 @@ static expr_ty bitwise_and_raw(Parser *); static expr_ty bitwise_and_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -13101,7 +13101,7 @@ bitwise_and_rule(Parser *p) static expr_ty bitwise_and_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13189,7 +13189,7 @@ static expr_ty shift_expr_raw(Parser *); static expr_ty shift_expr_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -13223,7 +13223,7 @@ shift_expr_rule(Parser *p) static expr_ty shift_expr_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13369,7 +13369,7 @@ static expr_ty sum_raw(Parser *); static expr_ty sum_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -13403,7 +13403,7 @@ sum_rule(Parser *p) static expr_ty sum_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13537,7 +13537,7 @@ static expr_ty term_raw(Parser *); static expr_ty term_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -13571,7 +13571,7 @@ term_rule(Parser *p) static expr_ty term_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13832,7 +13832,7 @@ term_raw(Parser *p) static expr_ty factor_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -13992,7 +13992,7 @@ factor_rule(Parser *p) static expr_ty power_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14078,7 +14078,7 @@ power_rule(Parser *p) static expr_ty await_primary_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14173,7 +14173,7 @@ static expr_ty primary_raw(Parser *); static expr_ty primary_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -14207,7 +14207,7 @@ primary_rule(Parser *p) static expr_ty primary_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14413,7 +14413,7 @@ primary_raw(Parser *p) static expr_ty slices_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14504,7 +14504,7 @@ slices_rule(Parser *p) static expr_ty slice_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14608,7 +14608,7 @@ slice_rule(Parser *p) static expr_ty atom_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14890,7 +14890,7 @@ atom_rule(Parser *p) static expr_ty group_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -14958,7 +14958,7 @@ group_rule(Parser *p) static expr_ty lambdef_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15028,7 +15028,7 @@ lambdef_rule(Parser *p) static arguments_ty lambda_params_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15090,7 +15090,7 @@ lambda_params_rule(Parser *p) static arguments_ty lambda_parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15255,7 +15255,7 @@ lambda_parameters_rule(Parser *p) static asdl_arg_seq* lambda_slash_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15335,7 +15335,7 @@ lambda_slash_no_default_rule(Parser *p) static SlashWithDefault* lambda_slash_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15423,7 +15423,7 @@ lambda_slash_with_default_rule(Parser *p) static StarEtc* lambda_star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15551,7 +15551,7 @@ lambda_star_etc_rule(Parser *p) static arg_ty lambda_kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15616,7 +15616,7 @@ lambda_kwds_rule(Parser *p) static arg_ty lambda_param_no_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15688,7 +15688,7 @@ lambda_param_no_default_rule(Parser *p) static NameDefaultPair* lambda_param_with_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15766,7 +15766,7 @@ lambda_param_with_default_rule(Parser *p) static NameDefaultPair* lambda_param_maybe_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15844,7 +15844,7 @@ lambda_param_maybe_default_rule(Parser *p) static arg_ty lambda_param_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15905,7 +15905,7 @@ lambda_param_rule(Parser *p) static expr_ty fstring_middle_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -15969,7 +15969,7 @@ fstring_middle_rule(Parser *p) static expr_ty fstring_replacement_field_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16064,7 +16064,7 @@ fstring_replacement_field_rule(Parser *p) static ResultTokenWithMetadata* fstring_conversion_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16110,7 +16110,7 @@ fstring_conversion_rule(Parser *p) static ResultTokenWithMetadata* fstring_full_format_spec_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16174,7 +16174,7 @@ fstring_full_format_spec_rule(Parser *p) static expr_ty fstring_format_spec_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16236,7 +16236,7 @@ fstring_format_spec_rule(Parser *p) static expr_ty fstring_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16285,7 +16285,7 @@ fstring_rule(Parser *p) static expr_ty string_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16328,7 +16328,7 @@ string_rule(Parser *p) static expr_ty strings_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16394,7 +16394,7 @@ strings_rule(Parser *p) static expr_ty list_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16461,7 +16461,7 @@ list_rule(Parser *p) static expr_ty tuple_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16528,7 +16528,7 @@ tuple_rule(Parser *p) static expr_ty set_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16595,7 +16595,7 @@ set_rule(Parser *p) static expr_ty dict_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16687,7 +16687,7 @@ dict_rule(Parser *p) static asdl_seq* double_starred_kvpairs_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16734,7 +16734,7 @@ double_starred_kvpairs_rule(Parser *p) static KeyValuePair* double_starred_kvpair_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16799,7 +16799,7 @@ double_starred_kvpair_rule(Parser *p) static KeyValuePair* kvpair_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16848,7 +16848,7 @@ kvpair_rule(Parser *p) static asdl_comprehension_seq* for_if_clauses_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -16895,7 +16895,7 @@ for_if_clauses_rule(Parser *p) static comprehension_ty for_if_clause_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17041,7 +17041,7 @@ for_if_clause_rule(Parser *p) static expr_ty listcomp_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17130,7 +17130,7 @@ listcomp_rule(Parser *p) static expr_ty setcomp_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17221,7 +17221,7 @@ setcomp_rule(Parser *p) static expr_ty genexp_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17310,7 +17310,7 @@ genexp_rule(Parser *p) static expr_ty dictcomp_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17399,7 +17399,7 @@ dictcomp_rule(Parser *p) static expr_ty arguments_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17474,7 +17474,7 @@ arguments_rule(Parser *p) static expr_ty args_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17574,7 +17574,7 @@ args_rule(Parser *p) static asdl_seq* kwargs_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17664,7 +17664,7 @@ kwargs_rule(Parser *p) static expr_ty starred_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17766,7 +17766,7 @@ starred_expression_rule(Parser *p) static KeywordOrStarred* kwarg_or_starred_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17876,7 +17876,7 @@ kwarg_or_starred_rule(Parser *p) static KeywordOrStarred* kwarg_or_double_starred_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -17998,7 +17998,7 @@ kwarg_or_double_starred_rule(Parser *p) static expr_ty star_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18092,7 +18092,7 @@ star_targets_rule(Parser *p) static asdl_expr_seq* star_targets_list_seq_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18139,7 +18139,7 @@ star_targets_list_seq_rule(Parser *p) static asdl_expr_seq* star_targets_tuple_seq_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18216,7 +18216,7 @@ star_targets_tuple_seq_rule(Parser *p) static expr_ty star_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18307,7 +18307,7 @@ star_target_rule(Parser *p) static expr_ty target_with_star_atom_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18448,7 +18448,7 @@ target_with_star_atom_rule(Parser *p) static expr_ty star_atom_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18608,7 +18608,7 @@ star_atom_rule(Parser *p) static expr_ty single_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18702,7 +18702,7 @@ single_target_rule(Parser *p) static expr_ty single_subscript_attribute_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -18822,7 +18822,7 @@ static expr_ty t_primary_raw(Parser *); static expr_ty t_primary_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } expr_ty _res = NULL; @@ -18856,7 +18856,7 @@ t_primary_rule(Parser *p) static expr_ty t_primary_raw(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19077,7 +19077,7 @@ t_primary_raw(Parser *p) static void * t_lookahead_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19153,7 +19153,7 @@ t_lookahead_rule(Parser *p) static asdl_expr_seq* del_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19203,7 +19203,7 @@ del_targets_rule(Parser *p) static expr_ty del_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19340,7 +19340,7 @@ del_target_rule(Parser *p) static expr_ty del_t_atom_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19507,7 +19507,7 @@ del_t_atom_rule(Parser *p) static asdl_expr_seq* type_expressions_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19751,7 +19751,7 @@ type_expressions_rule(Parser *p) static Token* func_type_comment_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -19844,7 +19844,7 @@ func_type_comment_rule(Parser *p) static void * invalid_arguments_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20087,7 +20087,7 @@ invalid_arguments_rule(Parser *p) static void * invalid_kwarg_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20233,7 +20233,7 @@ expression_without_invalid_rule(Parser *p) { int _prev_call_invalid = p->call_invalid_rules; p->call_invalid_rules = 0; - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20352,7 +20352,7 @@ expression_without_invalid_rule(Parser *p) static void * invalid_legacy_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20400,7 +20400,7 @@ invalid_legacy_expression_rule(Parser *p) static void * invalid_type_param_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20491,7 +20491,7 @@ invalid_type_param_rule(Parser *p) static void * invalid_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20708,7 +20708,7 @@ invalid_expression_rule(Parser *p) static void * invalid_named_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -20834,7 +20834,7 @@ invalid_named_expression_rule(Parser *p) static void * invalid_assignment_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21039,7 +21039,7 @@ invalid_assignment_rule(Parser *p) static expr_ty invalid_ann_assign_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21126,7 +21126,7 @@ invalid_ann_assign_target_rule(Parser *p) static void * invalid_del_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21172,7 +21172,7 @@ invalid_del_stmt_rule(Parser *p) static void * invalid_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21220,7 +21220,7 @@ invalid_block_rule(Parser *p) static void * invalid_comprehension_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21338,7 +21338,7 @@ invalid_comprehension_rule(Parser *p) static void * invalid_dict_comprehension_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21399,7 +21399,7 @@ invalid_dict_comprehension_rule(Parser *p) static void * invalid_parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21616,7 +21616,7 @@ invalid_parameters_rule(Parser *p) static void * invalid_default_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21665,7 +21665,7 @@ invalid_default_rule(Parser *p) static void * invalid_star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21807,7 +21807,7 @@ invalid_star_etc_rule(Parser *p) static void * invalid_kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21922,7 +21922,7 @@ invalid_kwds_rule(Parser *p) static void * invalid_parameters_helper_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -21990,7 +21990,7 @@ invalid_parameters_helper_rule(Parser *p) static void * invalid_lambda_parameters_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22209,7 +22209,7 @@ invalid_lambda_parameters_rule(Parser *p) static void * invalid_lambda_parameters_helper_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22274,7 +22274,7 @@ invalid_lambda_parameters_helper_rule(Parser *p) static void * invalid_lambda_star_etc_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22389,7 +22389,7 @@ invalid_lambda_star_etc_rule(Parser *p) static void * invalid_lambda_kwds_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22504,7 +22504,7 @@ invalid_lambda_kwds_rule(Parser *p) static void * invalid_double_type_comments_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22559,7 +22559,7 @@ invalid_double_type_comments_rule(Parser *p) static void * invalid_with_item_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22610,7 +22610,7 @@ invalid_with_item_rule(Parser *p) static void * invalid_for_if_clause_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22662,7 +22662,7 @@ invalid_for_if_clause_rule(Parser *p) static void * invalid_for_target_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22712,7 +22712,7 @@ invalid_for_target_rule(Parser *p) static void * invalid_group_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22794,7 +22794,7 @@ invalid_group_rule(Parser *p) static void * invalid_import_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22873,7 +22873,7 @@ invalid_import_rule(Parser *p) static void * invalid_import_from_targets_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -22948,7 +22948,7 @@ invalid_import_from_targets_rule(Parser *p) static void * invalid_with_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23047,7 +23047,7 @@ invalid_with_stmt_rule(Parser *p) static void * invalid_with_stmt_indent_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23158,7 +23158,7 @@ invalid_with_stmt_indent_rule(Parser *p) static void * invalid_try_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23337,7 +23337,7 @@ invalid_try_stmt_rule(Parser *p) static void * invalid_except_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23494,7 +23494,7 @@ invalid_except_stmt_rule(Parser *p) static void * invalid_except_star_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23659,7 +23659,7 @@ invalid_except_star_stmt_rule(Parser *p) static void * invalid_finally_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23712,7 +23712,7 @@ invalid_finally_stmt_rule(Parser *p) static void * invalid_except_stmt_indent_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23803,7 +23803,7 @@ invalid_except_stmt_indent_rule(Parser *p) static void * invalid_except_star_stmt_indent_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23866,7 +23866,7 @@ invalid_except_star_stmt_indent_rule(Parser *p) static void * invalid_match_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -23952,7 +23952,7 @@ invalid_match_stmt_rule(Parser *p) static void * invalid_case_block_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24044,7 +24044,7 @@ invalid_case_block_rule(Parser *p) static void * invalid_as_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24123,7 +24123,7 @@ invalid_as_pattern_rule(Parser *p) static void * invalid_class_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24173,7 +24173,7 @@ invalid_class_pattern_rule(Parser *p) static asdl_pattern_seq* invalid_class_argument_pattern_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24228,7 +24228,7 @@ invalid_class_argument_pattern_rule(Parser *p) static void * invalid_if_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24314,7 +24314,7 @@ invalid_if_stmt_rule(Parser *p) static void * invalid_elif_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24398,7 +24398,7 @@ invalid_elif_stmt_rule(Parser *p) static void * invalid_else_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24451,7 +24451,7 @@ invalid_else_stmt_rule(Parser *p) static void * invalid_while_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24537,7 +24537,7 @@ invalid_while_stmt_rule(Parser *p) static void * invalid_for_stmt_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24643,7 +24643,7 @@ invalid_for_stmt_rule(Parser *p) static void * invalid_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24775,7 +24775,7 @@ invalid_def_raw_rule(Parser *p) static void * invalid_class_def_raw_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24878,7 +24878,7 @@ invalid_class_def_raw_rule(Parser *p) static void * invalid_double_starred_kvpairs_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -24987,7 +24987,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) static void * invalid_kvpair_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25094,7 +25094,7 @@ invalid_kvpair_rule(Parser *p) static void * invalid_starred_expression_unpacking_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25146,7 +25146,7 @@ invalid_starred_expression_unpacking_rule(Parser *p) static void * invalid_starred_expression_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25200,7 +25200,7 @@ invalid_starred_expression_rule(Parser *p) static void * invalid_replacement_field_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25560,7 +25560,7 @@ invalid_replacement_field_rule(Parser *p) static void * invalid_conversion_character_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25631,7 +25631,7 @@ invalid_conversion_character_rule(Parser *p) static void * invalid_arithmetic_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25683,7 +25683,7 @@ invalid_arithmetic_rule(Parser *p) static void * invalid_factor_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25732,7 +25732,7 @@ invalid_factor_rule(Parser *p) static void * invalid_type_params_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25778,7 +25778,7 @@ invalid_type_params_rule(Parser *p) static asdl_seq * _loop0_1_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25845,7 +25845,7 @@ _loop0_1_rule(Parser *p) static asdl_seq * _loop1_2_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25917,7 +25917,7 @@ _loop1_2_rule(Parser *p) static asdl_seq * _loop0_3_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -25993,7 +25993,7 @@ _loop0_3_rule(Parser *p) static asdl_seq * _gather_4_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26034,7 +26034,7 @@ _gather_4_rule(Parser *p) static void * _tmp_5_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26091,7 +26091,7 @@ _tmp_5_rule(Parser *p) static void * _tmp_6_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26167,7 +26167,7 @@ _tmp_6_rule(Parser *p) static void * _tmp_7_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26224,7 +26224,7 @@ _tmp_7_rule(Parser *p) static void * _tmp_8_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26281,7 +26281,7 @@ _tmp_8_rule(Parser *p) static void * _tmp_9_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26338,7 +26338,7 @@ _tmp_9_rule(Parser *p) static void * _tmp_10_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26384,7 +26384,7 @@ _tmp_10_rule(Parser *p) static void * _tmp_11_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26452,7 +26452,7 @@ _tmp_11_rule(Parser *p) static asdl_seq * _loop1_12_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26524,7 +26524,7 @@ _loop1_12_rule(Parser *p) static void * _tmp_13_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26570,7 +26570,7 @@ _tmp_13_rule(Parser *p) static asdl_seq * _loop0_14_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26646,7 +26646,7 @@ _loop0_14_rule(Parser *p) static asdl_seq * _gather_15_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26687,7 +26687,7 @@ _gather_15_rule(Parser *p) static void * _tmp_16_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26744,7 +26744,7 @@ _tmp_16_rule(Parser *p) static void * _tmp_17_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26790,7 +26790,7 @@ _tmp_17_rule(Parser *p) static asdl_seq * _loop0_18_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26857,7 +26857,7 @@ _loop0_18_rule(Parser *p) static asdl_seq * _loop1_19_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -26929,7 +26929,7 @@ _loop1_19_rule(Parser *p) static asdl_seq * _loop0_20_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27005,7 +27005,7 @@ _loop0_20_rule(Parser *p) static asdl_seq * _gather_21_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27046,7 +27046,7 @@ _gather_21_rule(Parser *p) static void * _tmp_22_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27092,7 +27092,7 @@ _tmp_22_rule(Parser *p) static asdl_seq * _loop0_23_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27168,7 +27168,7 @@ _loop0_23_rule(Parser *p) static asdl_seq * _gather_24_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27209,7 +27209,7 @@ _gather_24_rule(Parser *p) static asdl_seq * _loop1_25_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27281,7 +27281,7 @@ _loop1_25_rule(Parser *p) static void * _tmp_26_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27330,7 +27330,7 @@ _tmp_26_rule(Parser *p) static void * _tmp_27_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27376,7 +27376,7 @@ _tmp_27_rule(Parser *p) static asdl_seq * _loop0_28_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27443,7 +27443,7 @@ _loop0_28_rule(Parser *p) static asdl_seq * _loop0_29_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27510,7 +27510,7 @@ _loop0_29_rule(Parser *p) static asdl_seq * _loop1_30_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27582,7 +27582,7 @@ _loop1_30_rule(Parser *p) static asdl_seq * _loop1_31_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27654,7 +27654,7 @@ _loop1_31_rule(Parser *p) static asdl_seq * _loop0_32_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27721,7 +27721,7 @@ _loop0_32_rule(Parser *p) static asdl_seq * _loop1_33_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27793,7 +27793,7 @@ _loop1_33_rule(Parser *p) static asdl_seq * _loop0_34_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27869,7 +27869,7 @@ _loop0_34_rule(Parser *p) static asdl_seq * _gather_35_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27910,7 +27910,7 @@ _gather_35_rule(Parser *p) static void * _tmp_36_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -27986,7 +27986,7 @@ _tmp_36_rule(Parser *p) static asdl_seq * _loop1_37_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28058,7 +28058,7 @@ _loop1_37_rule(Parser *p) static asdl_seq * _loop1_38_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28130,7 +28130,7 @@ _loop1_38_rule(Parser *p) static asdl_seq * _loop1_39_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28202,7 +28202,7 @@ _loop1_39_rule(Parser *p) static asdl_seq * _loop0_40_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28278,7 +28278,7 @@ _loop0_40_rule(Parser *p) static asdl_seq * _gather_41_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28319,7 +28319,7 @@ _gather_41_rule(Parser *p) static void * _tmp_42_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28376,7 +28376,7 @@ _tmp_42_rule(Parser *p) static void * _tmp_43_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28452,7 +28452,7 @@ _tmp_43_rule(Parser *p) static asdl_seq * _loop0_44_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28528,7 +28528,7 @@ _loop0_44_rule(Parser *p) static asdl_seq * _gather_45_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28569,7 +28569,7 @@ _gather_45_rule(Parser *p) static asdl_seq * _loop0_46_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28645,7 +28645,7 @@ _loop0_46_rule(Parser *p) static asdl_seq * _gather_47_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28686,7 +28686,7 @@ _gather_47_rule(Parser *p) static void * _tmp_48_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28743,7 +28743,7 @@ _tmp_48_rule(Parser *p) static asdl_seq * _loop0_49_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28819,7 +28819,7 @@ _loop0_49_rule(Parser *p) static asdl_seq * _gather_50_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28860,7 +28860,7 @@ _gather_50_rule(Parser *p) static asdl_seq * _loop0_51_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28936,7 +28936,7 @@ _loop0_51_rule(Parser *p) static asdl_seq * _gather_52_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -28977,7 +28977,7 @@ _gather_52_rule(Parser *p) static asdl_seq * _loop0_53_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29053,7 +29053,7 @@ _loop0_53_rule(Parser *p) static asdl_seq * _gather_54_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29094,7 +29094,7 @@ _gather_54_rule(Parser *p) static asdl_seq * _loop1_55_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29166,7 +29166,7 @@ _loop1_55_rule(Parser *p) static asdl_seq * _loop1_56_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29238,7 +29238,7 @@ _loop1_56_rule(Parser *p) static asdl_seq * _loop0_57_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29314,7 +29314,7 @@ _loop0_57_rule(Parser *p) static asdl_seq * _gather_58_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29355,7 +29355,7 @@ _gather_58_rule(Parser *p) static asdl_seq * _loop1_59_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29427,7 +29427,7 @@ _loop1_59_rule(Parser *p) static asdl_seq * _loop1_60_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29499,7 +29499,7 @@ _loop1_60_rule(Parser *p) static asdl_seq * _loop1_61_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29571,7 +29571,7 @@ _loop1_61_rule(Parser *p) static void * _tmp_62_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29614,7 +29614,7 @@ _tmp_62_rule(Parser *p) static asdl_seq * _loop0_63_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29690,7 +29690,7 @@ _loop0_63_rule(Parser *p) static asdl_seq * _gather_64_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29731,7 +29731,7 @@ _gather_64_rule(Parser *p) static void * _tmp_65_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29777,7 +29777,7 @@ _tmp_65_rule(Parser *p) static void * _tmp_66_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29834,7 +29834,7 @@ _tmp_66_rule(Parser *p) static void * _tmp_67_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29910,7 +29910,7 @@ _tmp_67_rule(Parser *p) static void * _tmp_68_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -29967,7 +29967,7 @@ _tmp_68_rule(Parser *p) static void * _tmp_69_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30062,7 +30062,7 @@ _tmp_69_rule(Parser *p) static void * _tmp_70_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30119,7 +30119,7 @@ _tmp_70_rule(Parser *p) static asdl_seq * _loop0_71_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30186,7 +30186,7 @@ _loop0_71_rule(Parser *p) static asdl_seq * _loop0_72_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30253,7 +30253,7 @@ _loop0_72_rule(Parser *p) static asdl_seq * _loop1_73_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30325,7 +30325,7 @@ _loop1_73_rule(Parser *p) static asdl_seq * _loop1_74_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30397,7 +30397,7 @@ _loop1_74_rule(Parser *p) static asdl_seq * _loop0_75_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30464,7 +30464,7 @@ _loop0_75_rule(Parser *p) static asdl_seq * _loop1_76_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30536,7 +30536,7 @@ _loop1_76_rule(Parser *p) static asdl_seq * _loop0_77_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30603,7 +30603,7 @@ _loop0_77_rule(Parser *p) static asdl_seq * _loop0_78_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30670,7 +30670,7 @@ _loop0_78_rule(Parser *p) static asdl_seq * _loop1_79_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30742,7 +30742,7 @@ _loop1_79_rule(Parser *p) static void * _tmp_80_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30791,7 +30791,7 @@ _tmp_80_rule(Parser *p) static asdl_seq * _loop0_81_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30867,7 +30867,7 @@ _loop0_81_rule(Parser *p) static asdl_seq * _gather_82_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30908,7 +30908,7 @@ _gather_82_rule(Parser *p) static asdl_seq * _loop1_83_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -30980,7 +30980,7 @@ _loop1_83_rule(Parser *p) static asdl_seq * _loop0_84_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31047,7 +31047,7 @@ _loop0_84_rule(Parser *p) static void * _tmp_85_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31106,7 +31106,7 @@ _tmp_85_rule(Parser *p) static asdl_seq * _loop0_86_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31183,7 +31183,7 @@ _loop0_86_rule(Parser *p) static asdl_seq * _gather_87_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31224,7 +31224,7 @@ _gather_87_rule(Parser *p) static void * _tmp_88_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31270,7 +31270,7 @@ _tmp_88_rule(Parser *p) static asdl_seq * _loop0_89_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31346,7 +31346,7 @@ _loop0_89_rule(Parser *p) static asdl_seq * _gather_90_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31387,7 +31387,7 @@ _gather_90_rule(Parser *p) static asdl_seq * _loop0_91_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31463,7 +31463,7 @@ _loop0_91_rule(Parser *p) static asdl_seq * _gather_92_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31504,7 +31504,7 @@ _gather_92_rule(Parser *p) static asdl_seq * _loop0_93_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31571,7 +31571,7 @@ _loop0_93_rule(Parser *p) static asdl_seq * _loop0_94_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31647,7 +31647,7 @@ _loop0_94_rule(Parser *p) static asdl_seq * _gather_95_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31688,7 +31688,7 @@ _gather_95_rule(Parser *p) static asdl_seq * _loop1_96_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31760,7 +31760,7 @@ _loop1_96_rule(Parser *p) static void * _tmp_97_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31800,7 +31800,7 @@ _tmp_97_rule(Parser *p) static asdl_seq * _loop0_98_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31876,7 +31876,7 @@ _loop0_98_rule(Parser *p) static asdl_seq * _gather_99_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31917,7 +31917,7 @@ _gather_99_rule(Parser *p) static asdl_seq * _loop0_100_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -31993,7 +31993,7 @@ _loop0_100_rule(Parser *p) static asdl_seq * _gather_101_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32034,7 +32034,7 @@ _gather_101_rule(Parser *p) static void * _tmp_102_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32077,7 +32077,7 @@ _tmp_102_rule(Parser *p) static void * _tmp_103_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32134,7 +32134,7 @@ _tmp_103_rule(Parser *p) static asdl_seq * _loop0_104_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32210,7 +32210,7 @@ _loop0_104_rule(Parser *p) static asdl_seq * _gather_105_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32251,7 +32251,7 @@ _gather_105_rule(Parser *p) static void * _tmp_106_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32311,7 +32311,7 @@ _tmp_106_rule(Parser *p) static void * _tmp_107_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32352,7 +32352,7 @@ _tmp_107_rule(Parser *p) static void * _tmp_108_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32409,7 +32409,7 @@ _tmp_108_rule(Parser *p) static void * _tmp_109_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32485,7 +32485,7 @@ _tmp_109_rule(Parser *p) static void * _tmp_110_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32526,7 +32526,7 @@ _tmp_110_rule(Parser *p) static asdl_seq * _loop1_111_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32598,7 +32598,7 @@ _loop1_111_rule(Parser *p) static void * _tmp_112_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32658,7 +32658,7 @@ _tmp_112_rule(Parser *p) static void * _tmp_113_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32715,7 +32715,7 @@ _tmp_113_rule(Parser *p) static void * _tmp_114_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32791,7 +32791,7 @@ _tmp_114_rule(Parser *p) static void * _tmp_115_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32848,7 +32848,7 @@ _tmp_115_rule(Parser *p) static void * _tmp_116_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -32981,7 +32981,7 @@ _tmp_116_rule(Parser *p) static asdl_seq * _loop0_117_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33048,7 +33048,7 @@ _loop0_117_rule(Parser *p) static asdl_seq * _loop0_118_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33115,7 +33115,7 @@ _loop0_118_rule(Parser *p) static void * _tmp_119_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33191,7 +33191,7 @@ _tmp_119_rule(Parser *p) static void * _tmp_120_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33248,7 +33248,7 @@ _tmp_120_rule(Parser *p) static void * _tmp_121_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33305,7 +33305,7 @@ _tmp_121_rule(Parser *p) static void * _tmp_122_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33362,7 +33362,7 @@ _tmp_122_rule(Parser *p) static void * _tmp_123_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33419,7 +33419,7 @@ _tmp_123_rule(Parser *p) static void * _tmp_124_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33479,7 +33479,7 @@ _tmp_124_rule(Parser *p) static void * _tmp_125_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33536,7 +33536,7 @@ _tmp_125_rule(Parser *p) static void * _tmp_126_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33612,7 +33612,7 @@ _tmp_126_rule(Parser *p) static void * _tmp_127_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33669,7 +33669,7 @@ _tmp_127_rule(Parser *p) static asdl_seq * _loop0_128_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33745,7 +33745,7 @@ _loop0_128_rule(Parser *p) static asdl_seq * _gather_129_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33786,7 +33786,7 @@ _gather_129_rule(Parser *p) static void * _tmp_130_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33843,7 +33843,7 @@ _tmp_130_rule(Parser *p) static void * _tmp_131_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33903,7 +33903,7 @@ _tmp_131_rule(Parser *p) static void * _tmp_132_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -33960,7 +33960,7 @@ _tmp_132_rule(Parser *p) static void * _tmp_133_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34005,7 +34005,7 @@ _tmp_133_rule(Parser *p) static asdl_seq * _loop0_134_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34081,7 +34081,7 @@ _loop0_134_rule(Parser *p) static asdl_seq * _gather_135_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34122,7 +34122,7 @@ _gather_135_rule(Parser *p) static asdl_seq * _loop0_136_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34198,7 +34198,7 @@ _loop0_136_rule(Parser *p) static asdl_seq * _gather_137_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34239,7 +34239,7 @@ _gather_137_rule(Parser *p) static asdl_seq * _loop0_138_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34315,7 +34315,7 @@ _loop0_138_rule(Parser *p) static asdl_seq * _gather_139_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34356,7 +34356,7 @@ _gather_139_rule(Parser *p) static void * _tmp_140_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34413,7 +34413,7 @@ _tmp_140_rule(Parser *p) static asdl_seq * _loop0_141_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34480,7 +34480,7 @@ _loop0_141_rule(Parser *p) static void * _tmp_142_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34522,7 +34522,7 @@ _tmp_142_rule(Parser *p) static void * _tmp_143_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34579,7 +34579,7 @@ _tmp_143_rule(Parser *p) static void * _tmp_144_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34620,7 +34620,7 @@ _tmp_144_rule(Parser *p) static void * _tmp_145_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34677,7 +34677,7 @@ _tmp_145_rule(Parser *p) static void * _tmp_146_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34772,7 +34772,7 @@ _tmp_146_rule(Parser *p) static void * _tmp_147_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34848,7 +34848,7 @@ _tmp_147_rule(Parser *p) static void * _tmp_148_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34889,7 +34889,7 @@ _tmp_148_rule(Parser *p) static void * _tmp_149_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -34946,7 +34946,7 @@ _tmp_149_rule(Parser *p) static void * _tmp_150_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35098,7 +35098,7 @@ _tmp_150_rule(Parser *p) static void * _tmp_151_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35174,7 +35174,7 @@ _tmp_151_rule(Parser *p) static void * _tmp_152_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35220,7 +35220,7 @@ _tmp_152_rule(Parser *p) static void * _tmp_153_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35277,7 +35277,7 @@ _tmp_153_rule(Parser *p) static void * _tmp_154_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35326,7 +35326,7 @@ _tmp_154_rule(Parser *p) static void * _tmp_155_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35372,7 +35372,7 @@ _tmp_155_rule(Parser *p) static void * _tmp_156_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35418,7 +35418,7 @@ _tmp_156_rule(Parser *p) static void * _tmp_157_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35464,7 +35464,7 @@ _tmp_157_rule(Parser *p) static void * _tmp_158_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35521,7 +35521,7 @@ _tmp_158_rule(Parser *p) static void * _tmp_159_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35578,7 +35578,7 @@ _tmp_159_rule(Parser *p) static void * _tmp_160_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35624,7 +35624,7 @@ _tmp_160_rule(Parser *p) static void * _tmp_161_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35683,7 +35683,7 @@ _tmp_161_rule(Parser *p) static void * _tmp_162_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35730,7 +35730,7 @@ _tmp_162_rule(Parser *p) static void * _tmp_163_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35774,7 +35774,7 @@ _tmp_163_rule(Parser *p) static void * _tmp_164_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35814,7 +35814,7 @@ _tmp_164_rule(Parser *p) static void * _tmp_165_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35854,7 +35854,7 @@ _tmp_165_rule(Parser *p) static void * _tmp_166_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35911,7 +35911,7 @@ _tmp_166_rule(Parser *p) static void * _tmp_167_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -35968,7 +35968,7 @@ _tmp_167_rule(Parser *p) static asdl_seq * _loop0_168_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -36035,7 +36035,7 @@ _loop0_168_rule(Parser *p) static void * _tmp_169_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -36077,7 +36077,7 @@ _tmp_169_rule(Parser *p) static void * _tmp_170_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -36119,7 +36119,7 @@ _tmp_170_rule(Parser *p) static void * _tmp_171_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { @@ -36160,7 +36160,7 @@ _tmp_171_rule(Parser *p) static void * _tmp_172_rule(Parser *p) { - if (p->level++ == MAXSTACK) { + if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) { _Pypegen_stack_overflow(p); } if (p->error_indicator) { diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 4adf72a8537a51..638e3f67e1cfdd 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -13,11 +13,6 @@ #include "structmember.h" #include -struct validator { - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ -}; - // Forward declaration static int init_types(void *arg); @@ -392,8 +387,7 @@ GENERATE_ASDL_SEQ_CONSTRUCTOR(pattern, pattern_ty) GENERATE_ASDL_SEQ_CONSTRUCTOR(type_ignore, type_ignore_ty) GENERATE_ASDL_SEQ_CONSTRUCTOR(type_param, type_param_ty) -static PyObject* ast2obj_mod(struct ast_state *state, struct validator *vstate, - void*); +static PyObject* ast2obj_mod(struct ast_state *state, void*); static const char * const Module_fields[]={ "body", "type_ignores", @@ -414,8 +408,7 @@ static const char * const stmt_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_stmt(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_stmt(struct ast_state *state, void*); static const char * const FunctionDef_fields[]={ "name", "args", @@ -550,8 +543,7 @@ static const char * const expr_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_expr(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_expr(struct ast_state *state, void*); static const char * const BoolOp_fields[]={ "op", "values", @@ -664,18 +656,12 @@ static const char * const Slice_fields[]={ "upper", "step", }; -static PyObject* ast2obj_expr_context(struct ast_state *state, struct validator - *vstate, expr_context_ty); -static PyObject* ast2obj_boolop(struct ast_state *state, struct validator - *vstate, boolop_ty); -static PyObject* ast2obj_operator(struct ast_state *state, struct validator - *vstate, operator_ty); -static PyObject* ast2obj_unaryop(struct ast_state *state, struct validator - *vstate, unaryop_ty); -static PyObject* ast2obj_cmpop(struct ast_state *state, struct validator - *vstate, cmpop_ty); -static PyObject* ast2obj_comprehension(struct ast_state *state, struct - validator *vstate, void*); +static PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty); +static PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty); +static PyObject* ast2obj_operator(struct ast_state *state, operator_ty); +static PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty); +static PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty); +static PyObject* ast2obj_comprehension(struct ast_state *state, void*); static const char * const comprehension_fields[]={ "target", "iter", @@ -688,15 +674,13 @@ static const char * const excepthandler_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_excepthandler(struct ast_state *state, struct - validator *vstate, void*); +static PyObject* ast2obj_excepthandler(struct ast_state *state, void*); static const char * const ExceptHandler_fields[]={ "type", "name", "body", }; -static PyObject* ast2obj_arguments(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_arguments(struct ast_state *state, void*); static const char * const arguments_fields[]={ "posonlyargs", "args", @@ -706,8 +690,7 @@ static const char * const arguments_fields[]={ "kwarg", "defaults", }; -static PyObject* ast2obj_arg(struct ast_state *state, struct validator *vstate, - void*); +static PyObject* ast2obj_arg(struct ast_state *state, void*); static const char * const arg_attributes[] = { "lineno", "col_offset", @@ -719,8 +702,7 @@ static const char * const arg_fields[]={ "annotation", "type_comment", }; -static PyObject* ast2obj_keyword(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_keyword(struct ast_state *state, void*); static const char * const keyword_attributes[] = { "lineno", "col_offset", @@ -731,8 +713,7 @@ static const char * const keyword_fields[]={ "arg", "value", }; -static PyObject* ast2obj_alias(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_alias(struct ast_state *state, void*); static const char * const alias_attributes[] = { "lineno", "col_offset", @@ -743,14 +724,12 @@ static const char * const alias_fields[]={ "name", "asname", }; -static PyObject* ast2obj_withitem(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_withitem(struct ast_state *state, void*); static const char * const withitem_fields[]={ "context_expr", "optional_vars", }; -static PyObject* ast2obj_match_case(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_match_case(struct ast_state *state, void*); static const char * const match_case_fields[]={ "pattern", "guard", @@ -762,8 +741,7 @@ static const char * const pattern_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_pattern(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_pattern(struct ast_state *state, void*); static const char * const MatchValue_fields[]={ "value", }; @@ -794,8 +772,7 @@ static const char * const MatchAs_fields[]={ static const char * const MatchOr_fields[]={ "patterns", }; -static PyObject* ast2obj_type_ignore(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_type_ignore(struct ast_state *state, void*); static const char * const TypeIgnore_fields[]={ "lineno", "tag", @@ -806,8 +783,7 @@ static const char * const type_param_attributes[] = { "end_lineno", "end_col_offset", }; -static PyObject* ast2obj_type_param(struct ast_state *state, struct validator - *vstate, void*); +static PyObject* ast2obj_type_param(struct ast_state *state, void*); static const char * const TypeVar_fields[]={ "name", "bound", @@ -5933,8 +5909,8 @@ add_attributes(struct ast_state *state, PyObject *type, const char * const *attr /* Conversion AST -> Python */ -static PyObject* ast2obj_list(struct ast_state *state, struct validator *vstate, asdl_seq *seq, - PyObject* (*func)(struct ast_state *state, struct validator *vstate, void*)) +static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, + PyObject* (*func)(struct ast_state *state, void*)) { Py_ssize_t i, n = asdl_seq_LEN(seq); PyObject *result = PyList_New(n); @@ -5942,7 +5918,7 @@ static PyObject* ast2obj_list(struct ast_state *state, struct validator *vstate, if (!result) return NULL; for (i = 0; i < n; i++) { - value = func(state, vstate, asdl_seq_GET_UNTYPED(seq, i)); + value = func(state, asdl_seq_GET_UNTYPED(seq, i)); if (!value) { Py_DECREF(result); return NULL; @@ -5952,7 +5928,7 @@ static PyObject* ast2obj_list(struct ast_state *state, struct validator *vstate, return result; } -static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), struct validator *Py_UNUSED(vstate), void *o) +static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o) { PyObject *op = (PyObject*)o; if (!op) { @@ -5964,7 +5940,7 @@ static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), struct valid #define ast2obj_identifier ast2obj_object #define ast2obj_string ast2obj_object -static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), struct validator *Py_UNUSED(vstate), long b) +static PyObject* ast2obj_int(struct ast_state *Py_UNUSED(state), long b) { return PyLong_FromLong(b); } @@ -8712,7 +8688,7 @@ _PyAST_TypeVarTuple(identifier name, expr_ty default_value, int lineno, int PyObject* -ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_mod(struct ast_state *state, void* _o) { mod_ty o = (mod_ty)_o; PyObject *result = NULL, *value = NULL; @@ -8720,9 +8696,7 @@ ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -8730,14 +8704,12 @@ ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Module_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Module.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Module.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.Module.type_ignores, + value = ast2obj_list(state, (asdl_seq*)o->v.Module.type_ignores, ast2obj_type_ignore); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_ignores, value) == -1) @@ -8748,7 +8720,7 @@ ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Interactive_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Interactive.body, + value = ast2obj_list(state, (asdl_seq*)o->v.Interactive.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) @@ -8759,7 +8731,7 @@ ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Expression_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Expression.body); + value = ast2obj_expr(state, o->v.Expression.body); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -8769,31 +8741,30 @@ ast2obj_mod(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->FunctionType_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.FunctionType.argtypes, + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionType.argtypes, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->argtypes, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.FunctionType.returns); + value = ast2obj_expr(state, o->v.FunctionType.returns); if (!value) goto failed; if (PyObject_SetAttr(result, state->returns, value) == -1) goto failed; Py_DECREF(value); break; } - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_stmt(struct ast_state *state, void* _o) { stmt_ty o = (stmt_ty)_o; PyObject *result = NULL, *value = NULL; @@ -8801,9 +8772,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -8811,41 +8780,39 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->FunctionDef_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.FunctionDef.name); + value = ast2obj_identifier(state, o->v.FunctionDef.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_arguments(state, vstate, o->v.FunctionDef.args); + value = ast2obj_arguments(state, o->v.FunctionDef.args); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.FunctionDef.body, + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.FunctionDef.decorator_list, + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.decorator_list, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.FunctionDef.returns); + value = ast2obj_expr(state, o->v.FunctionDef.returns); if (!value) goto failed; if (PyObject_SetAttr(result, state->returns, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.FunctionDef.type_comment); + value = ast2obj_string(state, o->v.FunctionDef.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.FunctionDef.type_params, + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.type_params, ast2obj_type_param); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_params, value) == -1) @@ -8856,41 +8823,40 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->AsyncFunctionDef_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.AsyncFunctionDef.name); + value = ast2obj_identifier(state, o->v.AsyncFunctionDef.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_arguments(state, vstate, o->v.AsyncFunctionDef.args); + value = ast2obj_arguments(state, o->v.AsyncFunctionDef.args); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.AsyncFunctionDef.body, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFunctionDef.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFunctionDef.decorator_list, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.AsyncFunctionDef.returns); + value = ast2obj_expr(state, o->v.AsyncFunctionDef.returns); if (!value) goto failed; if (PyObject_SetAttr(result, state->returns, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.AsyncFunctionDef.type_comment); + value = ast2obj_string(state, o->v.AsyncFunctionDef.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFunctionDef.type_params, ast2obj_type_param); if (!value) goto failed; @@ -8902,38 +8868,36 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->ClassDef_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.ClassDef.name); + value = ast2obj_identifier(state, o->v.ClassDef.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.ClassDef.bases, + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.bases, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->bases, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.ClassDef.keywords, + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.keywords, ast2obj_keyword); if (!value) goto failed; if (PyObject_SetAttr(result, state->keywords, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.ClassDef.body, + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.ClassDef.decorator_list, + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.decorator_list, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->decorator_list, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.ClassDef.type_params, + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.type_params, ast2obj_type_param); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_params, value) == -1) @@ -8944,7 +8908,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Return_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Return.value); + value = ast2obj_expr(state, o->v.Return.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -8954,7 +8918,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Delete_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Delete.targets, + value = ast2obj_list(state, (asdl_seq*)o->v.Delete.targets, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->targets, value) == -1) @@ -8965,18 +8929,18 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Assign_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Assign.targets, + value = ast2obj_list(state, (asdl_seq*)o->v.Assign.targets, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->targets, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Assign.value); + value = ast2obj_expr(state, o->v.Assign.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.Assign.type_comment); + value = ast2obj_string(state, o->v.Assign.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; @@ -8986,19 +8950,18 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->TypeAlias_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.TypeAlias.name); + value = ast2obj_expr(state, o->v.TypeAlias.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.TypeAlias.type_params, + value = ast2obj_list(state, (asdl_seq*)o->v.TypeAlias.type_params, ast2obj_type_param); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_params, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.TypeAlias.value); + value = ast2obj_expr(state, o->v.TypeAlias.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9008,17 +8971,17 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->AugAssign_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.AugAssign.target); + value = ast2obj_expr(state, o->v.AugAssign.target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_operator(state, vstate, o->v.AugAssign.op); + value = ast2obj_operator(state, o->v.AugAssign.op); if (!value) goto failed; if (PyObject_SetAttr(result, state->op, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.AugAssign.value); + value = ast2obj_expr(state, o->v.AugAssign.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9028,22 +8991,22 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->AnnAssign_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.AnnAssign.target); + value = ast2obj_expr(state, o->v.AnnAssign.target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.AnnAssign.annotation); + value = ast2obj_expr(state, o->v.AnnAssign.annotation); if (!value) goto failed; if (PyObject_SetAttr(result, state->annotation, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.AnnAssign.value); + value = ast2obj_expr(state, o->v.AnnAssign.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->v.AnnAssign.simple); + value = ast2obj_int(state, o->v.AnnAssign.simple); if (!value) goto failed; if (PyObject_SetAttr(result, state->simple, value) == -1) goto failed; @@ -9053,29 +9016,27 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->For_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.For.target); + value = ast2obj_expr(state, o->v.For.target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.For.iter); + value = ast2obj_expr(state, o->v.For.iter); if (!value) goto failed; if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.For.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.For.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.For.orelse, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.For.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.For.type_comment); + value = ast2obj_string(state, o->v.For.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; @@ -9085,29 +9046,29 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->AsyncFor_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.AsyncFor.target); + value = ast2obj_expr(state, o->v.AsyncFor.target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.AsyncFor.iter); + value = ast2obj_expr(state, o->v.AsyncFor.iter); if (!value) goto failed; if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.AsyncFor.body, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.AsyncFor.orelse, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncFor.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.AsyncFor.type_comment); + value = ast2obj_string(state, o->v.AsyncFor.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; @@ -9117,19 +9078,17 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->While_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.While.test); + value = ast2obj_expr(state, o->v.While.test); if (!value) goto failed; if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.While.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.While.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.While.orelse, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.While.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -9139,19 +9098,17 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->If_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.If.test); + value = ast2obj_expr(state, o->v.If.test); if (!value) goto failed; if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.If.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.If.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.If.orelse, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.If.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -9161,19 +9118,18 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->With_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.With.items, + value = ast2obj_list(state, (asdl_seq*)o->v.With.items, ast2obj_withitem); if (!value) goto failed; if (PyObject_SetAttr(result, state->items, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.With.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.With.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.With.type_comment); + value = ast2obj_string(state, o->v.With.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; @@ -9183,19 +9139,19 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->AsyncWith_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.AsyncWith.items, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.items, ast2obj_withitem); if (!value) goto failed; if (PyObject_SetAttr(result, state->items, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.AsyncWith.body, + value = ast2obj_list(state, (asdl_seq*)o->v.AsyncWith.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.AsyncWith.type_comment); + value = ast2obj_string(state, o->v.AsyncWith.type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; @@ -9205,12 +9161,12 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Match_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Match.subject); + value = ast2obj_expr(state, o->v.Match.subject); if (!value) goto failed; if (PyObject_SetAttr(result, state->subject, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Match.cases, + value = ast2obj_list(state, (asdl_seq*)o->v.Match.cases, ast2obj_match_case); if (!value) goto failed; if (PyObject_SetAttr(result, state->cases, value) == -1) @@ -9221,12 +9177,12 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Raise_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Raise.exc); + value = ast2obj_expr(state, o->v.Raise.exc); if (!value) goto failed; if (PyObject_SetAttr(result, state->exc, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Raise.cause); + value = ast2obj_expr(state, o->v.Raise.cause); if (!value) goto failed; if (PyObject_SetAttr(result, state->cause, value) == -1) goto failed; @@ -9236,25 +9192,23 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Try_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Try.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Try.handlers, + value = ast2obj_list(state, (asdl_seq*)o->v.Try.handlers, ast2obj_excepthandler); if (!value) goto failed; if (PyObject_SetAttr(result, state->handlers, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Try.orelse, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.Try.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Try.finalbody, + value = ast2obj_list(state, (asdl_seq*)o->v.Try.finalbody, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->finalbody, value) == -1) @@ -9265,25 +9219,24 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->TryStar_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.TryStar.body, - ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.TryStar.handlers, + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.handlers, ast2obj_excepthandler); if (!value) goto failed; if (PyObject_SetAttr(result, state->handlers, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.TryStar.orelse, + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.TryStar.finalbody, + value = ast2obj_list(state, (asdl_seq*)o->v.TryStar.finalbody, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->finalbody, value) == -1) @@ -9294,12 +9247,12 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Assert_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Assert.test); + value = ast2obj_expr(state, o->v.Assert.test); if (!value) goto failed; if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Assert.msg); + value = ast2obj_expr(state, o->v.Assert.msg); if (!value) goto failed; if (PyObject_SetAttr(result, state->msg, value) == -1) goto failed; @@ -9309,7 +9262,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Import_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Import.names, + value = ast2obj_list(state, (asdl_seq*)o->v.Import.names, ast2obj_alias); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) @@ -9320,18 +9273,18 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->ImportFrom_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.ImportFrom.module); + value = ast2obj_identifier(state, o->v.ImportFrom.module); if (!value) goto failed; if (PyObject_SetAttr(result, state->module, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.ImportFrom.names, + value = ast2obj_list(state, (asdl_seq*)o->v.ImportFrom.names, ast2obj_alias); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->v.ImportFrom.level); + value = ast2obj_int(state, o->v.ImportFrom.level); if (!value) goto failed; if (PyObject_SetAttr(result, state->level, value) == -1) goto failed; @@ -9341,7 +9294,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Global_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Global.names, + value = ast2obj_list(state, (asdl_seq*)o->v.Global.names, ast2obj_identifier); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) @@ -9352,7 +9305,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Nonlocal_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Nonlocal.names, + value = ast2obj_list(state, (asdl_seq*)o->v.Nonlocal.names, ast2obj_identifier); if (!value) goto failed; if (PyObject_SetAttr(result, state->names, value) == -1) @@ -9363,7 +9316,7 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Expr_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Expr.value); + value = ast2obj_expr(state, o->v.Expr.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9385,37 +9338,37 @@ ast2obj_stmt(struct ast_state *state, struct validator *vstate, void* _o) if (!result) goto failed; break; } - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_expr(struct ast_state *state, void* _o) { expr_ty o = (expr_ty)_o; PyObject *result = NULL, *value = NULL; @@ -9423,9 +9376,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -9433,12 +9384,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->BoolOp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_boolop(state, vstate, o->v.BoolOp.op); + value = ast2obj_boolop(state, o->v.BoolOp.op); if (!value) goto failed; if (PyObject_SetAttr(result, state->op, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.BoolOp.values, + value = ast2obj_list(state, (asdl_seq*)o->v.BoolOp.values, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) @@ -9449,12 +9400,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->NamedExpr_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.NamedExpr.target); + value = ast2obj_expr(state, o->v.NamedExpr.target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.NamedExpr.value); + value = ast2obj_expr(state, o->v.NamedExpr.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9464,17 +9415,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->BinOp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.BinOp.left); + value = ast2obj_expr(state, o->v.BinOp.left); if (!value) goto failed; if (PyObject_SetAttr(result, state->left, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_operator(state, vstate, o->v.BinOp.op); + value = ast2obj_operator(state, o->v.BinOp.op); if (!value) goto failed; if (PyObject_SetAttr(result, state->op, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.BinOp.right); + value = ast2obj_expr(state, o->v.BinOp.right); if (!value) goto failed; if (PyObject_SetAttr(result, state->right, value) == -1) goto failed; @@ -9484,12 +9435,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->UnaryOp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_unaryop(state, vstate, o->v.UnaryOp.op); + value = ast2obj_unaryop(state, o->v.UnaryOp.op); if (!value) goto failed; if (PyObject_SetAttr(result, state->op, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.UnaryOp.operand); + value = ast2obj_expr(state, o->v.UnaryOp.operand); if (!value) goto failed; if (PyObject_SetAttr(result, state->operand, value) == -1) goto failed; @@ -9499,12 +9450,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Lambda_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_arguments(state, vstate, o->v.Lambda.args); + value = ast2obj_arguments(state, o->v.Lambda.args); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Lambda.body); + value = ast2obj_expr(state, o->v.Lambda.body); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; @@ -9514,17 +9465,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->IfExp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.IfExp.test); + value = ast2obj_expr(state, o->v.IfExp.test); if (!value) goto failed; if (PyObject_SetAttr(result, state->test, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.IfExp.body); + value = ast2obj_expr(state, o->v.IfExp.body); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.IfExp.orelse); + value = ast2obj_expr(state, o->v.IfExp.orelse); if (!value) goto failed; if (PyObject_SetAttr(result, state->orelse, value) == -1) goto failed; @@ -9534,14 +9485,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Dict_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Dict.keys, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Dict.keys, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->keys, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Dict.values, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Dict.values, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) goto failed; @@ -9551,8 +9500,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Set_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Set.elts, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Set.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; @@ -9562,13 +9510,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->ListComp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.ListComp.elt); + value = ast2obj_expr(state, o->v.ListComp.elt); if (!value) goto failed; if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.ListComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.ListComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -9579,12 +9526,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->SetComp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.SetComp.elt); + value = ast2obj_expr(state, o->v.SetComp.elt); if (!value) goto failed; if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.SetComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.SetComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -9595,18 +9542,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->DictComp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.DictComp.key); + value = ast2obj_expr(state, o->v.DictComp.key); if (!value) goto failed; if (PyObject_SetAttr(result, state->key, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.DictComp.value); + value = ast2obj_expr(state, o->v.DictComp.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.DictComp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.DictComp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -9617,13 +9563,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->GeneratorExp_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.GeneratorExp.elt); + value = ast2obj_expr(state, o->v.GeneratorExp.elt); if (!value) goto failed; if (PyObject_SetAttr(result, state->elt, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.GeneratorExp.generators, + value = ast2obj_list(state, (asdl_seq*)o->v.GeneratorExp.generators, ast2obj_comprehension); if (!value) goto failed; if (PyObject_SetAttr(result, state->generators, value) == -1) @@ -9634,7 +9579,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Await_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Await.value); + value = ast2obj_expr(state, o->v.Await.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9644,7 +9589,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Yield_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Yield.value); + value = ast2obj_expr(state, o->v.Yield.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9654,7 +9599,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->YieldFrom_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.YieldFrom.value); + value = ast2obj_expr(state, o->v.YieldFrom.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -9664,7 +9609,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Compare_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Compare.left); + value = ast2obj_expr(state, o->v.Compare.left); if (!value) goto failed; if (PyObject_SetAttr(result, state->left, value) == -1) goto failed; @@ -9674,14 +9619,14 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) value = PyList_New(n); if (!value) goto failed; for(i = 0; i < n; i++) - PyList_SET_ITEM(value, i, ast2obj_cmpop(state, vstate, (cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i))); + PyList_SET_ITEM(value, i, ast2obj_cmpop(state, (cmpop_ty)asdl_seq_GET(o->v.Compare.ops, i))); } if (!value) goto failed; if (PyObject_SetAttr(result, state->ops, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.Compare.comparators, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Compare.comparators, + ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->comparators, value) == -1) goto failed; @@ -9691,18 +9636,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Call_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Call.func); + value = ast2obj_expr(state, o->v.Call.func); if (!value) goto failed; if (PyObject_SetAttr(result, state->func, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Call.args, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Call.args, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Call.keywords, + value = ast2obj_list(state, (asdl_seq*)o->v.Call.keywords, ast2obj_keyword); if (!value) goto failed; if (PyObject_SetAttr(result, state->keywords, value) == -1) @@ -9713,17 +9657,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->FormattedValue_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.FormattedValue.value); + value = ast2obj_expr(state, o->v.FormattedValue.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->v.FormattedValue.conversion); + value = ast2obj_int(state, o->v.FormattedValue.conversion); if (!value) goto failed; if (PyObject_SetAttr(result, state->conversion, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.FormattedValue.format_spec); + value = ast2obj_expr(state, o->v.FormattedValue.format_spec); if (!value) goto failed; if (PyObject_SetAttr(result, state->format_spec, value) == -1) goto failed; @@ -9733,7 +9677,7 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->JoinedStr_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.JoinedStr.values, + value = ast2obj_list(state, (asdl_seq*)o->v.JoinedStr.values, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->values, value) == -1) @@ -9744,12 +9688,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Constant_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_constant(state, vstate, o->v.Constant.value); + value = ast2obj_constant(state, o->v.Constant.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.Constant.kind); + value = ast2obj_string(state, o->v.Constant.kind); if (!value) goto failed; if (PyObject_SetAttr(result, state->kind, value) == -1) goto failed; @@ -9759,17 +9703,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Attribute_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Attribute.value); + value = ast2obj_expr(state, o->v.Attribute.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_identifier(state, vstate, o->v.Attribute.attr); + value = ast2obj_identifier(state, o->v.Attribute.attr); if (!value) goto failed; if (PyObject_SetAttr(result, state->attr, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.Attribute.ctx); + value = ast2obj_expr_context(state, o->v.Attribute.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9779,17 +9723,17 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Subscript_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Subscript.value); + value = ast2obj_expr(state, o->v.Subscript.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Subscript.slice); + value = ast2obj_expr(state, o->v.Subscript.slice); if (!value) goto failed; if (PyObject_SetAttr(result, state->slice, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.Subscript.ctx); + value = ast2obj_expr_context(state, o->v.Subscript.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9799,12 +9743,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Starred_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Starred.value); + value = ast2obj_expr(state, o->v.Starred.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.Starred.ctx); + value = ast2obj_expr_context(state, o->v.Starred.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9814,12 +9758,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Name_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.Name.id); + value = ast2obj_identifier(state, o->v.Name.id); if (!value) goto failed; if (PyObject_SetAttr(result, state->id, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.Name.ctx); + value = ast2obj_expr_context(state, o->v.Name.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9829,13 +9773,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->List_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.List.elts, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.List.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.List.ctx); + value = ast2obj_expr_context(state, o->v.List.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9845,13 +9788,12 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Tuple_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.Tuple.elts, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->v.Tuple.elts, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->elts, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr_context(state, vstate, o->v.Tuple.ctx); + value = ast2obj_expr_context(state, o->v.Tuple.ctx); if (!value) goto failed; if (PyObject_SetAttr(result, state->ctx, value) == -1) goto failed; @@ -9861,54 +9803,53 @@ ast2obj_expr(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->Slice_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.Slice.lower); + value = ast2obj_expr(state, o->v.Slice.lower); if (!value) goto failed; if (PyObject_SetAttr(result, state->lower, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Slice.upper); + value = ast2obj_expr(state, o->v.Slice.upper); if (!value) goto failed; if (PyObject_SetAttr(result, state->upper, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.Slice.step); + value = ast2obj_expr(state, o->v.Slice.step); if (!value) goto failed; if (PyObject_SetAttr(result, state->step, value) == -1) goto failed; Py_DECREF(value); break; } - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } -PyObject* ast2obj_expr_context(struct ast_state *state, struct validator - *vstate, expr_context_ty o) +PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty o) { switch(o) { case Load: @@ -9920,8 +9861,7 @@ PyObject* ast2obj_expr_context(struct ast_state *state, struct validator } Py_UNREACHABLE(); } -PyObject* ast2obj_boolop(struct ast_state *state, struct validator *vstate, - boolop_ty o) +PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty o) { switch(o) { case And: @@ -9931,8 +9871,7 @@ PyObject* ast2obj_boolop(struct ast_state *state, struct validator *vstate, } Py_UNREACHABLE(); } -PyObject* ast2obj_operator(struct ast_state *state, struct validator *vstate, - operator_ty o) +PyObject* ast2obj_operator(struct ast_state *state, operator_ty o) { switch(o) { case Add: @@ -9964,8 +9903,7 @@ PyObject* ast2obj_operator(struct ast_state *state, struct validator *vstate, } Py_UNREACHABLE(); } -PyObject* ast2obj_unaryop(struct ast_state *state, struct validator *vstate, - unaryop_ty o) +PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty o) { switch(o) { case Invert: @@ -9979,8 +9917,7 @@ PyObject* ast2obj_unaryop(struct ast_state *state, struct validator *vstate, } Py_UNREACHABLE(); } -PyObject* ast2obj_cmpop(struct ast_state *state, struct validator *vstate, - cmpop_ty o) +PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty o) { switch(o) { case Eq: @@ -10007,8 +9944,7 @@ PyObject* ast2obj_cmpop(struct ast_state *state, struct validator *vstate, Py_UNREACHABLE(); } PyObject* -ast2obj_comprehension(struct ast_state *state, struct validator *vstate, void* - _o) +ast2obj_comprehension(struct ast_state *state, void* _o) { comprehension_ty o = (comprehension_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10016,46 +9952,43 @@ ast2obj_comprehension(struct ast_state *state, struct validator *vstate, void* if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->comprehension_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_expr(state, vstate, o->target); + value = ast2obj_expr(state, o->target); if (!value) goto failed; if (PyObject_SetAttr(result, state->target, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->iter); + value = ast2obj_expr(state, o->iter); if (!value) goto failed; if (PyObject_SetAttr(result, state->iter, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->ifs, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->ifs, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->ifs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->is_async); + value = ast2obj_int(state, o->is_async); if (!value) goto failed; if (PyObject_SetAttr(result, state->is_async, value) == -1) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_excepthandler(struct ast_state *state, struct validator *vstate, void* - _o) +ast2obj_excepthandler(struct ast_state *state, void* _o) { excepthandler_ty o = (excepthandler_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10063,9 +9996,7 @@ ast2obj_excepthandler(struct ast_state *state, struct validator *vstate, void* if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -10073,17 +10004,17 @@ ast2obj_excepthandler(struct ast_state *state, struct validator *vstate, void* tp = (PyTypeObject *)state->ExceptHandler_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.ExceptHandler.type); + value = ast2obj_expr(state, o->v.ExceptHandler.type); if (!value) goto failed; if (PyObject_SetAttr(result, state->type, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_identifier(state, vstate, o->v.ExceptHandler.name); + value = ast2obj_identifier(state, o->v.ExceptHandler.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.ExceptHandler.body, + value = ast2obj_list(state, (asdl_seq*)o->v.ExceptHandler.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) @@ -10091,37 +10022,37 @@ ast2obj_excepthandler(struct ast_state *state, struct validator *vstate, void* Py_DECREF(value); break; } - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_arguments(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_arguments(struct ast_state *state, void* _o) { arguments_ty o = (arguments_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10129,61 +10060,58 @@ ast2obj_arguments(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->arguments_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_list(state, vstate, (asdl_seq*)o->posonlyargs, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->posonlyargs, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->posonlyargs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->args, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->args, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->args, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_arg(state, vstate, o->vararg); + value = ast2obj_arg(state, o->vararg); if (!value) goto failed; if (PyObject_SetAttr(result, state->vararg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->kwonlyargs, ast2obj_arg); + value = ast2obj_list(state, (asdl_seq*)o->kwonlyargs, ast2obj_arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->kwonlyargs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->kw_defaults, - ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->kw_defaults, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->kw_defaults, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_arg(state, vstate, o->kwarg); + value = ast2obj_arg(state, o->kwarg); if (!value) goto failed; if (PyObject_SetAttr(result, state->kwarg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->defaults, ast2obj_expr); + value = ast2obj_list(state, (asdl_seq*)o->defaults, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->defaults, value) == -1) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_arg(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_arg(struct ast_state *state, void* _o) { arg_ty o = (arg_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10191,60 +10119,58 @@ ast2obj_arg(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->arg_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_identifier(state, vstate, o->arg); + value = ast2obj_identifier(state, o->arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->arg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->annotation); + value = ast2obj_expr(state, o->annotation); if (!value) goto failed; if (PyObject_SetAttr(result, state->annotation, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->type_comment); + value = ast2obj_string(state, o->type_comment); if (!value) goto failed; if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_keyword(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_keyword(struct ast_state *state, void* _o) { keyword_ty o = (keyword_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10252,55 +10178,53 @@ ast2obj_keyword(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->keyword_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_identifier(state, vstate, o->arg); + value = ast2obj_identifier(state, o->arg); if (!value) goto failed; if (PyObject_SetAttr(result, state->arg, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->value); + value = ast2obj_expr(state, o->value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_alias(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_alias(struct ast_state *state, void* _o) { alias_ty o = (alias_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10308,55 +10232,53 @@ ast2obj_alias(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->alias_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_identifier(state, vstate, o->name); + value = ast2obj_identifier(state, o->name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_identifier(state, vstate, o->asname); + value = ast2obj_identifier(state, o->asname); if (!value) goto failed; if (PyObject_SetAttr(result, state->asname, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_withitem(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_withitem(struct ast_state *state, void* _o) { withitem_ty o = (withitem_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10364,35 +10286,33 @@ ast2obj_withitem(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->withitem_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_expr(state, vstate, o->context_expr); + value = ast2obj_expr(state, o->context_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->context_expr, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->optional_vars); + value = ast2obj_expr(state, o->optional_vars); if (!value) goto failed; if (PyObject_SetAttr(result, state->optional_vars, value) == -1) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_match_case(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_match_case(struct ast_state *state, void* _o) { match_case_ty o = (match_case_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10400,40 +10320,38 @@ ast2obj_match_case(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } tp = (PyTypeObject *)state->match_case_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) return NULL; - value = ast2obj_pattern(state, vstate, o->pattern); + value = ast2obj_pattern(state, o->pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->pattern, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->guard); + value = ast2obj_expr(state, o->guard); if (!value) goto failed; if (PyObject_SetAttr(result, state->guard, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, (asdl_seq*)o->body, ast2obj_stmt); + value = ast2obj_list(state, (asdl_seq*)o->body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttr(result, state->body, value) == -1) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_pattern(struct ast_state *state, void* _o) { pattern_ty o = (pattern_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10441,9 +10359,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -10451,7 +10367,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchValue_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.MatchValue.value); + value = ast2obj_expr(state, o->v.MatchValue.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -10461,7 +10377,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchSingleton_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_constant(state, vstate, o->v.MatchSingleton.value); + value = ast2obj_constant(state, o->v.MatchSingleton.value); if (!value) goto failed; if (PyObject_SetAttr(result, state->value, value) == -1) goto failed; @@ -10471,8 +10387,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchSequence_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.MatchSequence.patterns, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchSequence.patterns, ast2obj_pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->patterns, value) == -1) @@ -10483,20 +10398,19 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchMapping_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.MatchMapping.keys, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchMapping.keys, ast2obj_expr); if (!value) goto failed; if (PyObject_SetAttr(result, state->keys, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.MatchMapping.patterns, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchMapping.patterns, ast2obj_pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->patterns, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_identifier(state, vstate, o->v.MatchMapping.rest); + value = ast2obj_identifier(state, o->v.MatchMapping.rest); if (!value) goto failed; if (PyObject_SetAttr(result, state->rest, value) == -1) goto failed; @@ -10506,27 +10420,24 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchClass_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(state, vstate, o->v.MatchClass.cls); + value = ast2obj_expr(state, o->v.MatchClass.cls); if (!value) goto failed; if (PyObject_SetAttr(result, state->cls, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.MatchClass.patterns, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.patterns, ast2obj_pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->patterns, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.MatchClass.kwd_attrs, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.kwd_attrs, ast2obj_identifier); if (!value) goto failed; if (PyObject_SetAttr(result, state->kwd_attrs, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(state, vstate, - (asdl_seq*)o->v.MatchClass.kwd_patterns, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchClass.kwd_patterns, ast2obj_pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->kwd_patterns, value) == -1) @@ -10537,7 +10448,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchStar_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.MatchStar.name); + value = ast2obj_identifier(state, o->v.MatchStar.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; @@ -10547,12 +10458,12 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchAs_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_pattern(state, vstate, o->v.MatchAs.pattern); + value = ast2obj_pattern(state, o->v.MatchAs.pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->pattern, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_identifier(state, vstate, o->v.MatchAs.name); + value = ast2obj_identifier(state, o->v.MatchAs.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; @@ -10562,7 +10473,7 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->MatchOr_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(state, vstate, (asdl_seq*)o->v.MatchOr.patterns, + value = ast2obj_list(state, (asdl_seq*)o->v.MatchOr.patterns, ast2obj_pattern); if (!value) goto failed; if (PyObject_SetAttr(result, state->patterns, value) == -1) @@ -10570,37 +10481,37 @@ ast2obj_pattern(struct ast_state *state, struct validator *vstate, void* _o) Py_DECREF(value); break; } - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_type_ignore(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_type_ignore(struct ast_state *state, void* _o) { type_ignore_ty o = (type_ignore_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10608,9 +10519,7 @@ ast2obj_type_ignore(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -10618,29 +10527,29 @@ ast2obj_type_ignore(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->TypeIgnore_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_int(state, vstate, o->v.TypeIgnore.lineno); + value = ast2obj_int(state, o->v.TypeIgnore.lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_string(state, vstate, o->v.TypeIgnore.tag); + value = ast2obj_string(state, o->v.TypeIgnore.tag); if (!value) goto failed; if (PyObject_SetAttr(result, state->tag, value) == -1) goto failed; Py_DECREF(value); break; } - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; } PyObject* -ast2obj_type_param(struct ast_state *state, struct validator *vstate, void* _o) +ast2obj_type_param(struct ast_state *state, void* _o) { type_param_ty o = (type_param_ty)_o; PyObject *result = NULL, *value = NULL; @@ -10648,9 +10557,7 @@ ast2obj_type_param(struct ast_state *state, struct validator *vstate, void* _o) if (!o) { Py_RETURN_NONE; } - if (++vstate->recursion_depth > vstate->recursion_limit) { - PyErr_SetString(PyExc_RecursionError, - "maximum recursion depth exceeded during ast construction"); + if (Py_EnterRecursiveCall("during ast construction")) { return NULL; } switch (o->kind) { @@ -10658,17 +10565,17 @@ ast2obj_type_param(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->TypeVar_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.TypeVar.name); + value = ast2obj_identifier(state, o->v.TypeVar.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.TypeVar.bound); + value = ast2obj_expr(state, o->v.TypeVar.bound); if (!value) goto failed; if (PyObject_SetAttr(result, state->bound, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.TypeVar.default_value); + value = ast2obj_expr(state, o->v.TypeVar.default_value); if (!value) goto failed; if (PyObject_SetAttr(result, state->default_value, value) == -1) goto failed; @@ -10678,12 +10585,12 @@ ast2obj_type_param(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->ParamSpec_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.ParamSpec.name); + value = ast2obj_identifier(state, o->v.ParamSpec.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.ParamSpec.default_value); + value = ast2obj_expr(state, o->v.ParamSpec.default_value); if (!value) goto failed; if (PyObject_SetAttr(result, state->default_value, value) == -1) goto failed; @@ -10693,42 +10600,42 @@ ast2obj_type_param(struct ast_state *state, struct validator *vstate, void* _o) tp = (PyTypeObject *)state->TypeVarTuple_type; result = PyType_GenericNew(tp, NULL, NULL); if (!result) goto failed; - value = ast2obj_identifier(state, vstate, o->v.TypeVarTuple.name); + value = ast2obj_identifier(state, o->v.TypeVarTuple.name); if (!value) goto failed; if (PyObject_SetAttr(result, state->name, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(state, vstate, o->v.TypeVarTuple.default_value); + value = ast2obj_expr(state, o->v.TypeVarTuple.default_value); if (!value) goto failed; if (PyObject_SetAttr(result, state->default_value, value) == -1) goto failed; Py_DECREF(value); break; } - value = ast2obj_int(state, vstate, o->lineno); + value = ast2obj_int(state, o->lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->col_offset); + value = ast2obj_int(state, o->col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->col_offset, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_lineno); + value = ast2obj_int(state, o->end_lineno); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_lineno, value) < 0) goto failed; Py_DECREF(value); - value = ast2obj_int(state, vstate, o->end_col_offset); + value = ast2obj_int(state, o->end_col_offset); if (!value) goto failed; if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) goto failed; Py_DECREF(value); - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); return result; failed: - vstate->recursion_depth--; + Py_LeaveRecursiveCall(); Py_XDECREF(value); Py_XDECREF(result); return NULL; @@ -18135,28 +18042,8 @@ PyObject* PyAST_mod2obj(mod_ty t) if (state == NULL) { return NULL; } + PyObject *result = ast2obj_mod(state, t); - int starting_recursion_depth; - /* Be careful here to prevent overflow. */ - PyThreadState *tstate = _PyThreadState_GET(); - if (!tstate) { - return NULL; - } - struct validator vstate; - vstate.recursion_limit = Py_C_RECURSION_LIMIT; - int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; - starting_recursion_depth = recursion_depth; - vstate.recursion_depth = starting_recursion_depth; - - PyObject *result = ast2obj_mod(state, &vstate, t); - - /* Check that the recursion depth counting balanced correctly */ - if (result && vstate.recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "AST constructor recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, vstate.recursion_depth); - return NULL; - } return result; } diff --git a/Python/ast.c b/Python/ast.c index bf1ff5f3ec18ba..597df5b63b5f39 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -9,34 +9,22 @@ #include #include -struct validator { - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ -}; - -#define ENTER_RECURSIVE(ST) \ - do { \ - if (++(ST)->recursion_depth > (ST)->recursion_limit) { \ - PyErr_SetString(PyExc_RecursionError, \ - "maximum recursion depth exceeded during compilation"); \ - return 0; \ - } \ - } while(0) +#define ENTER_RECURSIVE() \ +if (Py_EnterRecursiveCall(" during compilation")) { \ + return 0; \ +} -#define LEAVE_RECURSIVE(ST) \ - do { \ - --(ST)->recursion_depth; \ - } while(0) +#define LEAVE_RECURSIVE() Py_LeaveRecursiveCall(); -static int validate_stmts(struct validator *, asdl_stmt_seq *); -static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int); -static int validate_patterns(struct validator *, asdl_pattern_seq *, int); -static int validate_type_params(struct validator *, asdl_type_param_seq *); +static int validate_stmts(asdl_stmt_seq *); +static int validate_exprs(asdl_expr_seq *, expr_context_ty, int); +static int validate_patterns(asdl_pattern_seq *, int); +static int validate_type_params(asdl_type_param_seq *); static int _validate_nonempty_seq(asdl_seq *, const char *, const char *); -static int validate_stmt(struct validator *, stmt_ty); -static int validate_expr(struct validator *, expr_ty, expr_context_ty); -static int validate_pattern(struct validator *, pattern_ty, int); -static int validate_typeparam(struct validator *, type_param_ty); +static int validate_stmt(stmt_ty); +static int validate_expr(expr_ty, expr_context_ty); +static int validate_pattern(pattern_ty, int); +static int validate_typeparam(type_param_ty); #define VALIDATE_POSITIONS(node) \ if (node->lineno > node->end_lineno) { \ @@ -80,7 +68,7 @@ validate_name(PyObject *name) } static int -validate_comprehension(struct validator *state, asdl_comprehension_seq *gens) +validate_comprehension(asdl_comprehension_seq *gens) { assert(!PyErr_Occurred()); if (!asdl_seq_LEN(gens)) { @@ -89,32 +77,32 @@ validate_comprehension(struct validator *state, asdl_comprehension_seq *gens) } for (Py_ssize_t i = 0; i < asdl_seq_LEN(gens); i++) { comprehension_ty comp = asdl_seq_GET(gens, i); - if (!validate_expr(state, comp->target, Store) || - !validate_expr(state, comp->iter, Load) || - !validate_exprs(state, comp->ifs, Load, 0)) + if (!validate_expr(comp->target, Store) || + !validate_expr(comp->iter, Load) || + !validate_exprs(comp->ifs, Load, 0)) return 0; } return 1; } static int -validate_keywords(struct validator *state, asdl_keyword_seq *keywords) +validate_keywords(asdl_keyword_seq *keywords) { assert(!PyErr_Occurred()); for (Py_ssize_t i = 0; i < asdl_seq_LEN(keywords); i++) - if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load)) + if (!validate_expr((asdl_seq_GET(keywords, i))->value, Load)) return 0; return 1; } static int -validate_args(struct validator *state, asdl_arg_seq *args) +validate_args(asdl_arg_seq *args) { assert(!PyErr_Occurred()); for (Py_ssize_t i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = asdl_seq_GET(args, i); VALIDATE_POSITIONS(arg); - if (arg->annotation && !validate_expr(state, arg->annotation, Load)) + if (arg->annotation && !validate_expr(arg->annotation, Load)) return 0; } return 1; @@ -136,20 +124,20 @@ expr_context_name(expr_context_ty ctx) } static int -validate_arguments(struct validator *state, arguments_ty args) +validate_arguments(arguments_ty args) { assert(!PyErr_Occurred()); - if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) { + if (!validate_args(args->posonlyargs) || !validate_args(args->args)) { return 0; } if (args->vararg && args->vararg->annotation - && !validate_expr(state, args->vararg->annotation, Load)) { + && !validate_expr(args->vararg->annotation, Load)) { return 0; } - if (!validate_args(state, args->kwonlyargs)) + if (!validate_args(args->kwonlyargs)) return 0; if (args->kwarg && args->kwarg->annotation - && !validate_expr(state, args->kwarg->annotation, Load)) { + && !validate_expr(args->kwarg->annotation, Load)) { return 0; } if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) { @@ -161,11 +149,11 @@ validate_arguments(struct validator *state, arguments_ty args) "kw_defaults on arguments"); return 0; } - return validate_exprs(state, args->defaults, Load, 0) && validate_exprs(state, args->kw_defaults, Load, 1); + return validate_exprs(args->defaults, Load, 0) && validate_exprs(args->kw_defaults, Load, 1); } static int -validate_constant(struct validator *state, PyObject *value) +validate_constant(PyObject *value) { assert(!PyErr_Occurred()); if (value == Py_None || value == Py_Ellipsis) @@ -180,7 +168,7 @@ validate_constant(struct validator *state, PyObject *value) return 1; if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) { - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); PyObject *it = PyObject_GetIter(value); if (it == NULL) @@ -196,7 +184,7 @@ validate_constant(struct validator *state, PyObject *value) break; } - if (!validate_constant(state, item)) { + if (!validate_constant(item)) { Py_DECREF(it); Py_DECREF(item); return 0; @@ -205,7 +193,7 @@ validate_constant(struct validator *state, PyObject *value) } Py_DECREF(it); - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return 1; } @@ -218,12 +206,12 @@ validate_constant(struct validator *state, PyObject *value) } static int -validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) +validate_expr(expr_ty exp, expr_context_ty ctx) { assert(!PyErr_Occurred()); VALIDATE_POSITIONS(exp); int ret = -1; - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); int check_ctx = 1; expr_context_ty actual_ctx; @@ -273,23 +261,23 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values"); return 0; } - ret = validate_exprs(state, exp->v.BoolOp.values, Load, 0); + ret = validate_exprs(exp->v.BoolOp.values, Load, 0); break; case BinOp_kind: - ret = validate_expr(state, exp->v.BinOp.left, Load) && - validate_expr(state, exp->v.BinOp.right, Load); + ret = validate_expr(exp->v.BinOp.left, Load) && + validate_expr(exp->v.BinOp.right, Load); break; case UnaryOp_kind: - ret = validate_expr(state, exp->v.UnaryOp.operand, Load); + ret = validate_expr(exp->v.UnaryOp.operand, Load); break; case Lambda_kind: - ret = validate_arguments(state, exp->v.Lambda.args) && - validate_expr(state, exp->v.Lambda.body, Load); + ret = validate_arguments(exp->v.Lambda.args) && + validate_expr(exp->v.Lambda.body, Load); break; case IfExp_kind: - ret = validate_expr(state, exp->v.IfExp.test, Load) && - validate_expr(state, exp->v.IfExp.body, Load) && - validate_expr(state, exp->v.IfExp.orelse, Load); + ret = validate_expr(exp->v.IfExp.test, Load) && + validate_expr(exp->v.IfExp.body, Load) && + validate_expr(exp->v.IfExp.orelse, Load); break; case Dict_kind: if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) { @@ -299,34 +287,34 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) } /* null_ok=1 for keys expressions to allow dict unpacking to work in dict literals, i.e. ``{**{a:b}}`` */ - ret = validate_exprs(state, exp->v.Dict.keys, Load, /*null_ok=*/ 1) && - validate_exprs(state, exp->v.Dict.values, Load, /*null_ok=*/ 0); + ret = validate_exprs(exp->v.Dict.keys, Load, /*null_ok=*/ 1) && + validate_exprs(exp->v.Dict.values, Load, /*null_ok=*/ 0); break; case Set_kind: - ret = validate_exprs(state, exp->v.Set.elts, Load, 0); + ret = validate_exprs(exp->v.Set.elts, Load, 0); break; #define COMP(NAME) \ case NAME ## _kind: \ - ret = validate_comprehension(state, exp->v.NAME.generators) && \ - validate_expr(state, exp->v.NAME.elt, Load); \ + ret = validate_comprehension(exp->v.NAME.generators) && \ + validate_expr(exp->v.NAME.elt, Load); \ break; COMP(ListComp) COMP(SetComp) COMP(GeneratorExp) #undef COMP case DictComp_kind: - ret = validate_comprehension(state, exp->v.DictComp.generators) && - validate_expr(state, exp->v.DictComp.key, Load) && - validate_expr(state, exp->v.DictComp.value, Load); + ret = validate_comprehension(exp->v.DictComp.generators) && + validate_expr(exp->v.DictComp.key, Load) && + validate_expr(exp->v.DictComp.value, Load); break; case Yield_kind: - ret = !exp->v.Yield.value || validate_expr(state, exp->v.Yield.value, Load); + ret = !exp->v.Yield.value || validate_expr(exp->v.Yield.value, Load); break; case YieldFrom_kind: - ret = validate_expr(state, exp->v.YieldFrom.value, Load); + ret = validate_expr(exp->v.YieldFrom.value, Load); break; case Await_kind: - ret = validate_expr(state, exp->v.Await.value, Load); + ret = validate_expr(exp->v.Await.value, Load); break; case Compare_kind: if (!asdl_seq_LEN(exp->v.Compare.comparators)) { @@ -339,52 +327,52 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) "of comparators and operands"); return 0; } - ret = validate_exprs(state, exp->v.Compare.comparators, Load, 0) && - validate_expr(state, exp->v.Compare.left, Load); + ret = validate_exprs(exp->v.Compare.comparators, Load, 0) && + validate_expr(exp->v.Compare.left, Load); break; case Call_kind: - ret = validate_expr(state, exp->v.Call.func, Load) && - validate_exprs(state, exp->v.Call.args, Load, 0) && - validate_keywords(state, exp->v.Call.keywords); + ret = validate_expr(exp->v.Call.func, Load) && + validate_exprs(exp->v.Call.args, Load, 0) && + validate_keywords(exp->v.Call.keywords); break; case Constant_kind: - if (!validate_constant(state, exp->v.Constant.value)) { + if (!validate_constant(exp->v.Constant.value)) { return 0; } ret = 1; break; case JoinedStr_kind: - ret = validate_exprs(state, exp->v.JoinedStr.values, Load, 0); + ret = validate_exprs(exp->v.JoinedStr.values, Load, 0); break; case FormattedValue_kind: - if (validate_expr(state, exp->v.FormattedValue.value, Load) == 0) + if (validate_expr(exp->v.FormattedValue.value, Load) == 0) return 0; if (exp->v.FormattedValue.format_spec) { - ret = validate_expr(state, exp->v.FormattedValue.format_spec, Load); + ret = validate_expr(exp->v.FormattedValue.format_spec, Load); break; } ret = 1; break; case Attribute_kind: - ret = validate_expr(state, exp->v.Attribute.value, Load); + ret = validate_expr(exp->v.Attribute.value, Load); break; case Subscript_kind: - ret = validate_expr(state, exp->v.Subscript.slice, Load) && - validate_expr(state, exp->v.Subscript.value, Load); + ret = validate_expr(exp->v.Subscript.slice, Load) && + validate_expr(exp->v.Subscript.value, Load); break; case Starred_kind: - ret = validate_expr(state, exp->v.Starred.value, ctx); + ret = validate_expr(exp->v.Starred.value, ctx); break; case Slice_kind: - ret = (!exp->v.Slice.lower || validate_expr(state, exp->v.Slice.lower, Load)) && - (!exp->v.Slice.upper || validate_expr(state, exp->v.Slice.upper, Load)) && - (!exp->v.Slice.step || validate_expr(state, exp->v.Slice.step, Load)); + ret = (!exp->v.Slice.lower || validate_expr(exp->v.Slice.lower, Load)) && + (!exp->v.Slice.upper || validate_expr(exp->v.Slice.upper, Load)) && + (!exp->v.Slice.step || validate_expr(exp->v.Slice.step, Load)); break; case List_kind: - ret = validate_exprs(state, exp->v.List.elts, ctx, 0); + ret = validate_exprs(exp->v.List.elts, ctx, 0); break; case Tuple_kind: - ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0); + ret = validate_exprs(exp->v.Tuple.elts, ctx, 0); break; case NamedExpr_kind: if (exp->v.NamedExpr.target->kind != Name_kind) { @@ -392,7 +380,7 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) "NamedExpr target must be a Name"); return 0; } - ret = validate_expr(state, exp->v.NamedExpr.value, Load); + ret = validate_expr(exp->v.NamedExpr.value, Load); break; /* This last case doesn't have any checking. */ case Name_kind: @@ -404,7 +392,7 @@ validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) PyErr_SetString(PyExc_SystemError, "unexpected expression"); ret = 0; } - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return ret; } @@ -480,10 +468,10 @@ ensure_literal_complex(expr_ty exp) } static int -validate_pattern_match_value(struct validator *state, expr_ty exp) +validate_pattern_match_value(expr_ty exp) { assert(!PyErr_Occurred()); - if (!validate_expr(state, exp, Load)) { + if (!validate_expr(exp, Load)) { return 0; } @@ -493,7 +481,7 @@ validate_pattern_match_value(struct validator *state, expr_ty exp) /* Ellipsis and immutable sequences are not allowed. For True, False and None, MatchSingleton() should be used */ - if (!validate_expr(state, exp, Load)) { + if (!validate_expr(exp, Load)) { return 0; } PyObject *literal = exp->v.Constant.value; @@ -545,15 +533,15 @@ validate_capture(PyObject *name) } static int -validate_pattern(struct validator *state, pattern_ty p, int star_ok) +validate_pattern(pattern_ty p, int star_ok) { assert(!PyErr_Occurred()); VALIDATE_POSITIONS(p); int ret = -1; - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); switch (p->kind) { case MatchValue_kind: - ret = validate_pattern_match_value(state, p->v.MatchValue.value); + ret = validate_pattern_match_value(p->v.MatchValue.value); break; case MatchSingleton_kind: ret = p->v.MatchSingleton.value == Py_None || PyBool_Check(p->v.MatchSingleton.value); @@ -563,7 +551,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) } break; case MatchSequence_kind: - ret = validate_patterns(state, p->v.MatchSequence.patterns, /*star_ok=*/1); + ret = validate_patterns(p->v.MatchSequence.patterns, /*star_ok=*/1); break; case MatchMapping_kind: if (asdl_seq_LEN(p->v.MatchMapping.keys) != asdl_seq_LEN(p->v.MatchMapping.patterns)) { @@ -591,7 +579,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) continue; } } - if (!validate_pattern_match_value(state, key)) { + if (!validate_pattern_match_value(key)) { ret = 0; break; } @@ -599,7 +587,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) if (ret == 0) { break; } - ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0); + ret = validate_patterns(p->v.MatchMapping.patterns, /*star_ok=*/0); break; case MatchClass_kind: if (asdl_seq_LEN(p->v.MatchClass.kwd_attrs) != asdl_seq_LEN(p->v.MatchClass.kwd_patterns)) { @@ -608,7 +596,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) ret = 0; break; } - if (!validate_expr(state, p->v.MatchClass.cls, Load)) { + if (!validate_expr(p->v.MatchClass.cls, Load)) { ret = 0; break; } @@ -644,12 +632,12 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) break; } - if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) { + if (!validate_patterns(p->v.MatchClass.patterns, /*star_ok=*/0)) { ret = 0; break; } - ret = validate_patterns(state, p->v.MatchClass.kwd_patterns, /*star_ok=*/0); + ret = validate_patterns(p->v.MatchClass.kwd_patterns, /*star_ok=*/0); break; case MatchStar_kind: if (!star_ok) { @@ -673,7 +661,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) ret = 0; } else { - ret = validate_pattern(state, p->v.MatchAs.pattern, /*star_ok=*/0); + ret = validate_pattern(p->v.MatchAs.pattern, /*star_ok=*/0); } break; case MatchOr_kind: @@ -683,7 +671,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) ret = 0; break; } - ret = validate_patterns(state, p->v.MatchOr.patterns, /*star_ok=*/0); + ret = validate_patterns(p->v.MatchOr.patterns, /*star_ok=*/0); break; // No default case, so the compiler will emit a warning if new pattern // kinds are added without being handled here @@ -692,7 +680,7 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) PyErr_SetString(PyExc_SystemError, "unexpected pattern"); ret = 0; } - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return ret; } @@ -707,56 +695,56 @@ _validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner) #define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner) static int -validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx) +validate_assignlist(asdl_expr_seq *targets, expr_context_ty ctx) { assert(!PyErr_Occurred()); return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") && - validate_exprs(state, targets, ctx, 0); + validate_exprs(targets, ctx, 0); } static int -validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner) +validate_body(asdl_stmt_seq *body, const char *owner) { assert(!PyErr_Occurred()); - return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body); + return validate_nonempty_seq(body, "body", owner) && validate_stmts(body); } static int -validate_stmt(struct validator *state, stmt_ty stmt) +validate_stmt(stmt_ty stmt) { assert(!PyErr_Occurred()); VALIDATE_POSITIONS(stmt); int ret = -1; - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); switch (stmt->kind) { case FunctionDef_kind: - ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") && - validate_type_params(state, stmt->v.FunctionDef.type_params) && - validate_arguments(state, stmt->v.FunctionDef.args) && - validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) && + ret = validate_body(stmt->v.FunctionDef.body, "FunctionDef") && + validate_type_params(stmt->v.FunctionDef.type_params) && + validate_arguments(stmt->v.FunctionDef.args) && + validate_exprs(stmt->v.FunctionDef.decorator_list, Load, 0) && (!stmt->v.FunctionDef.returns || - validate_expr(state, stmt->v.FunctionDef.returns, Load)); + validate_expr(stmt->v.FunctionDef.returns, Load)); break; case ClassDef_kind: - ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") && - validate_type_params(state, stmt->v.ClassDef.type_params) && - validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) && - validate_keywords(state, stmt->v.ClassDef.keywords) && - validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0); + ret = validate_body(stmt->v.ClassDef.body, "ClassDef") && + validate_type_params(stmt->v.ClassDef.type_params) && + validate_exprs(stmt->v.ClassDef.bases, Load, 0) && + validate_keywords(stmt->v.ClassDef.keywords) && + validate_exprs(stmt->v.ClassDef.decorator_list, Load, 0); break; case Return_kind: - ret = !stmt->v.Return.value || validate_expr(state, stmt->v.Return.value, Load); + ret = !stmt->v.Return.value || validate_expr(stmt->v.Return.value, Load); break; case Delete_kind: - ret = validate_assignlist(state, stmt->v.Delete.targets, Del); + ret = validate_assignlist(stmt->v.Delete.targets, Del); break; case Assign_kind: - ret = validate_assignlist(state, stmt->v.Assign.targets, Store) && - validate_expr(state, stmt->v.Assign.value, Load); + ret = validate_assignlist(stmt->v.Assign.targets, Store) && + validate_expr(stmt->v.Assign.value, Load); break; case AugAssign_kind: - ret = validate_expr(state, stmt->v.AugAssign.target, Store) && - validate_expr(state, stmt->v.AugAssign.value, Load); + ret = validate_expr(stmt->v.AugAssign.target, Store) && + validate_expr(stmt->v.AugAssign.value, Load); break; case AnnAssign_kind: if (stmt->v.AnnAssign.target->kind != Name_kind && @@ -765,10 +753,10 @@ validate_stmt(struct validator *state, stmt_ty stmt) "AnnAssign with simple non-Name target"); return 0; } - ret = validate_expr(state, stmt->v.AnnAssign.target, Store) && + ret = validate_expr(stmt->v.AnnAssign.target, Store) && (!stmt->v.AnnAssign.value || - validate_expr(state, stmt->v.AnnAssign.value, Load)) && - validate_expr(state, stmt->v.AnnAssign.annotation, Load); + validate_expr(stmt->v.AnnAssign.value, Load)) && + validate_expr(stmt->v.AnnAssign.annotation, Load); break; case TypeAlias_kind: if (stmt->v.TypeAlias.name->kind != Name_kind) { @@ -776,64 +764,64 @@ validate_stmt(struct validator *state, stmt_ty stmt) "TypeAlias with non-Name name"); return 0; } - ret = validate_expr(state, stmt->v.TypeAlias.name, Store) && - validate_type_params(state, stmt->v.TypeAlias.type_params) && - validate_expr(state, stmt->v.TypeAlias.value, Load); + ret = validate_expr(stmt->v.TypeAlias.name, Store) && + validate_type_params(stmt->v.TypeAlias.type_params) && + validate_expr(stmt->v.TypeAlias.value, Load); break; case For_kind: - ret = validate_expr(state, stmt->v.For.target, Store) && - validate_expr(state, stmt->v.For.iter, Load) && - validate_body(state, stmt->v.For.body, "For") && - validate_stmts(state, stmt->v.For.orelse); + ret = validate_expr(stmt->v.For.target, Store) && + validate_expr(stmt->v.For.iter, Load) && + validate_body(stmt->v.For.body, "For") && + validate_stmts(stmt->v.For.orelse); break; case AsyncFor_kind: - ret = validate_expr(state, stmt->v.AsyncFor.target, Store) && - validate_expr(state, stmt->v.AsyncFor.iter, Load) && - validate_body(state, stmt->v.AsyncFor.body, "AsyncFor") && - validate_stmts(state, stmt->v.AsyncFor.orelse); + ret = validate_expr(stmt->v.AsyncFor.target, Store) && + validate_expr(stmt->v.AsyncFor.iter, Load) && + validate_body(stmt->v.AsyncFor.body, "AsyncFor") && + validate_stmts(stmt->v.AsyncFor.orelse); break; case While_kind: - ret = validate_expr(state, stmt->v.While.test, Load) && - validate_body(state, stmt->v.While.body, "While") && - validate_stmts(state, stmt->v.While.orelse); + ret = validate_expr(stmt->v.While.test, Load) && + validate_body(stmt->v.While.body, "While") && + validate_stmts(stmt->v.While.orelse); break; case If_kind: - ret = validate_expr(state, stmt->v.If.test, Load) && - validate_body(state, stmt->v.If.body, "If") && - validate_stmts(state, stmt->v.If.orelse); + ret = validate_expr(stmt->v.If.test, Load) && + validate_body(stmt->v.If.body, "If") && + validate_stmts(stmt->v.If.orelse); break; case With_kind: if (!validate_nonempty_seq(stmt->v.With.items, "items", "With")) return 0; for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) { withitem_ty item = asdl_seq_GET(stmt->v.With.items, i); - if (!validate_expr(state, item->context_expr, Load) || - (item->optional_vars && !validate_expr(state, item->optional_vars, Store))) + if (!validate_expr(item->context_expr, Load) || + (item->optional_vars && !validate_expr(item->optional_vars, Store))) return 0; } - ret = validate_body(state, stmt->v.With.body, "With"); + ret = validate_body(stmt->v.With.body, "With"); break; case AsyncWith_kind: if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith")) return 0; for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) { withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i); - if (!validate_expr(state, item->context_expr, Load) || - (item->optional_vars && !validate_expr(state, item->optional_vars, Store))) + if (!validate_expr(item->context_expr, Load) || + (item->optional_vars && !validate_expr(item->optional_vars, Store))) return 0; } - ret = validate_body(state, stmt->v.AsyncWith.body, "AsyncWith"); + ret = validate_body(stmt->v.AsyncWith.body, "AsyncWith"); break; case Match_kind: - if (!validate_expr(state, stmt->v.Match.subject, Load) + if (!validate_expr(stmt->v.Match.subject, Load) || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) { return 0; } for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) { match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i); - if (!validate_pattern(state, m->pattern, /*star_ok=*/0) - || (m->guard && !validate_expr(state, m->guard, Load)) - || !validate_body(state, m->body, "match_case")) { + if (!validate_pattern(m->pattern, /*star_ok=*/0) + || (m->guard && !validate_expr(m->guard, Load)) + || !validate_body(m->body, "match_case")) { return 0; } } @@ -841,8 +829,8 @@ validate_stmt(struct validator *state, stmt_ty stmt) break; case Raise_kind: if (stmt->v.Raise.exc) { - ret = validate_expr(state, stmt->v.Raise.exc, Load) && - (!stmt->v.Raise.cause || validate_expr(state, stmt->v.Raise.cause, Load)); + ret = validate_expr(stmt->v.Raise.exc, Load) && + (!stmt->v.Raise.cause || validate_expr(stmt->v.Raise.cause, Load)); break; } if (stmt->v.Raise.cause) { @@ -852,7 +840,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) ret = 1; break; case Try_kind: - if (!validate_body(state, stmt->v.Try.body, "Try")) + if (!validate_body(stmt->v.Try.body, "Try")) return 0; if (!asdl_seq_LEN(stmt->v.Try.handlers) && !asdl_seq_LEN(stmt->v.Try.finalbody)) { @@ -868,17 +856,17 @@ validate_stmt(struct validator *state, stmt_ty stmt) excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i); VALIDATE_POSITIONS(handler); if ((handler->v.ExceptHandler.type && - !validate_expr(state, handler->v.ExceptHandler.type, Load)) || - !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler")) + !validate_expr(handler->v.ExceptHandler.type, Load)) || + !validate_body(handler->v.ExceptHandler.body, "ExceptHandler")) return 0; } ret = (!asdl_seq_LEN(stmt->v.Try.finalbody) || - validate_stmts(state, stmt->v.Try.finalbody)) && + validate_stmts(stmt->v.Try.finalbody)) && (!asdl_seq_LEN(stmt->v.Try.orelse) || - validate_stmts(state, stmt->v.Try.orelse)); + validate_stmts(stmt->v.Try.orelse)); break; case TryStar_kind: - if (!validate_body(state, stmt->v.TryStar.body, "TryStar")) + if (!validate_body(stmt->v.TryStar.body, "TryStar")) return 0; if (!asdl_seq_LEN(stmt->v.TryStar.handlers) && !asdl_seq_LEN(stmt->v.TryStar.finalbody)) { @@ -893,18 +881,18 @@ validate_stmt(struct validator *state, stmt_ty stmt) for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) { excepthandler_ty handler = asdl_seq_GET(stmt->v.TryStar.handlers, i); if ((handler->v.ExceptHandler.type && - !validate_expr(state, handler->v.ExceptHandler.type, Load)) || - !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler")) + !validate_expr(handler->v.ExceptHandler.type, Load)) || + !validate_body(handler->v.ExceptHandler.body, "ExceptHandler")) return 0; } ret = (!asdl_seq_LEN(stmt->v.TryStar.finalbody) || - validate_stmts(state, stmt->v.TryStar.finalbody)) && + validate_stmts(stmt->v.TryStar.finalbody)) && (!asdl_seq_LEN(stmt->v.TryStar.orelse) || - validate_stmts(state, stmt->v.TryStar.orelse)); + validate_stmts(stmt->v.TryStar.orelse)); break; case Assert_kind: - ret = validate_expr(state, stmt->v.Assert.test, Load) && - (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load)); + ret = validate_expr(stmt->v.Assert.test, Load) && + (!stmt->v.Assert.msg || validate_expr(stmt->v.Assert.msg, Load)); break; case Import_kind: ret = validate_nonempty_seq(stmt->v.Import.names, "names", "Import"); @@ -923,15 +911,15 @@ validate_stmt(struct validator *state, stmt_ty stmt) ret = validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal"); break; case Expr_kind: - ret = validate_expr(state, stmt->v.Expr.value, Load); + ret = validate_expr(stmt->v.Expr.value, Load); break; case AsyncFunctionDef_kind: - ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") && - validate_type_params(state, stmt->v.AsyncFunctionDef.type_params) && - validate_arguments(state, stmt->v.AsyncFunctionDef.args) && - validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) && + ret = validate_body(stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") && + validate_type_params(stmt->v.AsyncFunctionDef.type_params) && + validate_arguments(stmt->v.AsyncFunctionDef.args) && + validate_exprs(stmt->v.AsyncFunctionDef.decorator_list, Load, 0) && (!stmt->v.AsyncFunctionDef.returns || - validate_expr(state, stmt->v.AsyncFunctionDef.returns, Load)); + validate_expr(stmt->v.AsyncFunctionDef.returns, Load)); break; case Pass_kind: case Break_kind: @@ -944,18 +932,18 @@ validate_stmt(struct validator *state, stmt_ty stmt) PyErr_SetString(PyExc_SystemError, "unexpected statement"); ret = 0; } - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return ret; } static int -validate_stmts(struct validator *state, asdl_stmt_seq *seq) +validate_stmts(asdl_stmt_seq *seq) { assert(!PyErr_Occurred()); for (Py_ssize_t i = 0; i < asdl_seq_LEN(seq); i++) { stmt_ty stmt = asdl_seq_GET(seq, i); if (stmt) { - if (!validate_stmt(state, stmt)) + if (!validate_stmt(stmt)) return 0; } else { @@ -968,13 +956,13 @@ validate_stmts(struct validator *state, asdl_stmt_seq *seq) } static int -validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok) +validate_exprs(asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok) { assert(!PyErr_Occurred()); for (Py_ssize_t i = 0; i < asdl_seq_LEN(exprs); i++) { expr_ty expr = asdl_seq_GET(exprs, i); if (expr) { - if (!validate_expr(state, expr, ctx)) + if (!validate_expr(expr, ctx)) return 0; } else if (!null_ok) { @@ -988,12 +976,12 @@ validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ct } static int -validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok) +validate_patterns(asdl_pattern_seq *patterns, int star_ok) { assert(!PyErr_Occurred()); for (Py_ssize_t i = 0; i < asdl_seq_LEN(patterns); i++) { pattern_ty pattern = asdl_seq_GET(patterns, i); - if (!validate_pattern(state, pattern, star_ok)) { + if (!validate_pattern(pattern, star_ok)) { return 0; } } @@ -1001,7 +989,7 @@ validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ } static int -validate_typeparam(struct validator *state, type_param_ty tp) +validate_typeparam(type_param_ty tp) { VALIDATE_POSITIONS(tp); int ret = -1; @@ -1009,32 +997,32 @@ validate_typeparam(struct validator *state, type_param_ty tp) case TypeVar_kind: ret = validate_name(tp->v.TypeVar.name) && (!tp->v.TypeVar.bound || - validate_expr(state, tp->v.TypeVar.bound, Load)) && + validate_expr(tp->v.TypeVar.bound, Load)) && (!tp->v.TypeVar.default_value || - validate_expr(state, tp->v.TypeVar.default_value, Load)); + validate_expr(tp->v.TypeVar.default_value, Load)); break; case ParamSpec_kind: ret = validate_name(tp->v.ParamSpec.name) && (!tp->v.ParamSpec.default_value || - validate_expr(state, tp->v.ParamSpec.default_value, Load)); + validate_expr(tp->v.ParamSpec.default_value, Load)); break; case TypeVarTuple_kind: ret = validate_name(tp->v.TypeVarTuple.name) && (!tp->v.TypeVarTuple.default_value || - validate_expr(state, tp->v.TypeVarTuple.default_value, Load)); + validate_expr(tp->v.TypeVarTuple.default_value, Load)); break; } return ret; } static int -validate_type_params(struct validator *state, asdl_type_param_seq *tps) +validate_type_params(asdl_type_param_seq *tps) { Py_ssize_t i; for (i = 0; i < asdl_seq_LEN(tps); i++) { type_param_ty tp = asdl_seq_GET(tps, i); if (tp) { - if (!validate_typeparam(state, tp)) + if (!validate_typeparam(tp)) return 0; } } @@ -1046,34 +1034,20 @@ _PyAST_Validate(mod_ty mod) { assert(!PyErr_Occurred()); int res = -1; - struct validator state; - PyThreadState *tstate; - int starting_recursion_depth; - - /* Setup recursion depth check counters */ - tstate = _PyThreadState_GET(); - if (!tstate) { - return 0; - } - /* Be careful here to prevent overflow. */ - int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; - starting_recursion_depth = recursion_depth; - state.recursion_depth = starting_recursion_depth; - state.recursion_limit = Py_C_RECURSION_LIMIT; switch (mod->kind) { case Module_kind: - res = validate_stmts(&state, mod->v.Module.body); + res = validate_stmts(mod->v.Module.body); break; case Interactive_kind: - res = validate_stmts(&state, mod->v.Interactive.body); + res = validate_stmts(mod->v.Interactive.body); break; case Expression_kind: - res = validate_expr(&state, mod->v.Expression.body, Load); + res = validate_expr(mod->v.Expression.body, Load); break; case FunctionType_kind: - res = validate_exprs(&state, mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) && - validate_expr(&state, mod->v.FunctionType.returns, Load); + res = validate_exprs(mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) && + validate_expr(mod->v.FunctionType.returns, Load); break; // No default case so compiler emits warning for unhandled cases } @@ -1082,14 +1056,6 @@ _PyAST_Validate(mod_ty mod) PyErr_SetString(PyExc_SystemError, "impossible module node"); return 0; } - - /* Check that the recursion depth counting balanced correctly */ - if (res && state.recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "AST validator recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, state.recursion_depth); - return 0; - } return res; } diff --git a/Python/ast_opt.c b/Python/ast_opt.c index 1db9980d4fcd88..2c6e16817f2aad 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -10,24 +10,14 @@ typedef struct { int optimize; int ff_features; - - int recursion_depth; /* current recursion depth */ - int recursion_limit; /* recursion limit */ } _PyASTOptimizeState; -#define ENTER_RECURSIVE(ST) \ - do { \ - if (++(ST)->recursion_depth > (ST)->recursion_limit) { \ - PyErr_SetString(PyExc_RecursionError, \ - "maximum recursion depth exceeded during compilation"); \ - return 0; \ - } \ - } while(0) +#define ENTER_RECURSIVE() \ +if (Py_EnterRecursiveCall(" during compilation")) { \ + return 0; \ +} -#define LEAVE_RECURSIVE(ST) \ - do { \ - --(ST)->recursion_depth; \ - } while(0) +#define LEAVE_RECURSIVE() Py_LeaveRecursiveCall(); static int make_const(expr_ty node, PyObject *val, PyArena *arena) @@ -424,7 +414,7 @@ astfold_mod(mod_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) static int astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); switch (node_->kind) { case BoolOp_kind: CALL_SEQ(astfold_expr, expr, node_->v.BoolOp.values); @@ -520,7 +510,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) case Name_kind: if (node_->v.Name.ctx == Load && _PyUnicode_EqualToASCIIString(node_->v.Name.id, "__debug__")) { - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return make_const(node_, PyBool_FromLong(!state->optimize), ctx_); } break; @@ -533,7 +523,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) // No default case, so the compiler will emit a warning if new expression // kinds are added without being handled here } - LEAVE_RECURSIVE(state);; + LEAVE_RECURSIVE(); return 1; } @@ -578,7 +568,7 @@ astfold_arg(arg_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) static int astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) { - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); switch (node_->kind) { case FunctionDef_kind: CALL_SEQ(astfold_type_param, type_param, node_->v.FunctionDef.type_params); @@ -700,7 +690,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) // No default case, so the compiler will emit a warning if new statement // kinds are added without being handled here } - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return 1; } @@ -770,7 +760,7 @@ astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) // Currently, this is really only used to form complex/negative numeric // constants in MatchValue and MatchMapping nodes // We still recurse into all subexpressions and subpatterns anyway - ENTER_RECURSIVE(state); + ENTER_RECURSIVE(); switch (node_->kind) { case MatchValue_kind: CALL(fold_const_match_patterns, expr_ty, node_->v.MatchValue.value); @@ -802,7 +792,7 @@ astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) // No default case, so the compiler will emit a warning if new pattern // kinds are added without being handled here } - LEAVE_RECURSIVE(state); + LEAVE_RECURSIVE(); return 1; } @@ -840,34 +830,12 @@ astfold_type_param(type_param_ty node_, PyArena *ctx_, _PyASTOptimizeState *stat int _PyAST_Optimize(mod_ty mod, PyArena *arena, int optimize, int ff_features) { - PyThreadState *tstate; - int starting_recursion_depth; - _PyASTOptimizeState state; state.optimize = optimize; state.ff_features = ff_features; - /* Setup recursion depth check counters */ - tstate = _PyThreadState_GET(); - if (!tstate) { - return 0; - } - /* Be careful here to prevent overflow. */ - int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; - starting_recursion_depth = recursion_depth; - state.recursion_depth = starting_recursion_depth; - state.recursion_limit = Py_C_RECURSION_LIMIT; - int ret = astfold_mod(mod, arena, &state); assert(ret || PyErr_Occurred()); - /* Check that the recursion depth counting balanced correctly */ - if (ret && state.recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "AST optimizer recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, state.recursion_depth); - return 0; - } - return ret; } diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 1c5fdf847b62c2..3c5cb07709d66c 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1082,7 +1082,6 @@ dummy_func( /* Restore previous frame and return. */ tstate->current_frame = frame->previous; assert(!_PyErr_Occurred(tstate)); - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; PyObject *result = PyStackRef_AsPyObjectSteal(retval); SYNC_SP(); /* Not strictly necessary, but prevents warnings */ return result; @@ -3971,11 +3970,10 @@ dummy_func( EXIT_IF(!PyCFunction_CheckExact(callable_o)); EXIT_IF(PyCFunction_GET_FLAGS(callable_o) != METH_O); // CPython promises to check all non-vectorcall function calls. - EXIT_IF(tstate->c_recursion_remaining <= 0); + EXIT_IF(_Py_ReachedRecursionLimit(tstate)); STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o); _PyStackRef arg = args[0]; - _Py_EnterRecursiveCallTstateUnchecked(tstate); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable_o), PyStackRef_AsPyObjectBorrow(arg)); _Py_LeaveRecursiveCallTstate(tstate); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); @@ -4165,14 +4163,13 @@ dummy_func( PyMethodDef *meth = method->d_method; EXIT_IF(meth->ml_flags != METH_O); // CPython promises to check all non-vectorcall function calls. - EXIT_IF(tstate->c_recursion_remaining <= 0); + EXIT_IF(_Py_ReachedRecursionLimit(tstate)); _PyStackRef arg_stackref = arguments[1]; _PyStackRef self_stackref = arguments[0]; EXIT_IF(!Py_IS_TYPE(PyStackRef_AsPyObjectBorrow(self_stackref), method->d_common.d_type)); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyStackRef_AsPyObjectBorrow(self_stackref), PyStackRef_AsPyObjectBorrow(arg_stackref)); @@ -4247,10 +4244,9 @@ dummy_func( EXIT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); EXIT_IF(meth->ml_flags != METH_NOARGS); // CPython promises to check all non-vectorcall function calls. - EXIT_IF(tstate->c_recursion_remaining <= 0); + EXIT_IF(_Py_ReachedRecursionLimit(tstate)); STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, self, NULL); _Py_LeaveRecursiveCallTstate(tstate); assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); @@ -5252,7 +5248,6 @@ dummy_func( if (frame->owner == FRAME_OWNED_BY_INTERPRETER) { /* Restore previous frame and exit */ tstate->current_frame = frame->previous; - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; return NULL; } next_instr = frame->instr_ptr; diff --git a/Python/ceval.c b/Python/ceval.c index cf9a8713ed9803..0459c57c4cbaed 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -304,36 +304,106 @@ Py_SetRecursionLimit(int new_limit) _PyEval_StartTheWorld(interp); } +int +_Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count) +{ + char here; + uintptr_t here_addr = (uintptr_t)&here; + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + if (here_addr > _tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES) { + return 0; + } + if (_tstate->c_stack_hard_limit == 0) { + _Py_InitializeRecursionLimits(tstate); + } + return here_addr <= _tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES; +} + +void +_Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) +{ + char here; + uintptr_t here_addr = (uintptr_t)&here; + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + if (here_addr < _tstate->c_stack_hard_limit) { + Py_FatalError("Unchecked stack overflow."); + } +} + +#if defined(__s390x__) +# define Py_C_STACK_SIZE 320000 +#elif defined(_WIN32) + // Don't define Py_C_STACK_SIZE, ask the O/S +#elif defined(__ANDROID__) +# define Py_C_STACK_SIZE 1200000 +#elif defined(__sparc__) +# define Py_C_STACK_SIZE 1600000 +#elif defined(__wasi__) + /* Web assembly has two stacks, so this isn't really the stack depth */ +# define Py_C_STACK_SIZE 100000 +#elif defined(__hppa__) || defined(__powerpc64__) +# define Py_C_STACK_SIZE 2000000 +#else +# define Py_C_STACK_SIZE 5000000 +#endif + +void +_Py_InitializeRecursionLimits(PyThreadState *tstate) +{ + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; +#ifdef WIN32 + ULONG_PTR low, high; + GetCurrentThreadStackLimits(&low, &high); + _tstate->c_stack_top = (uintptr_t)high; + ULONG guarantee = 0; + SetThreadStackGuarantee(&guarantee); + _tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + PYOS_STACK_MARGIN_BYTES; + _tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; +#else + char here; + uintptr_t here_addr = (uintptr_t)&here; + _tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096); + _tstate->c_stack_soft_limit = _tstate->c_stack_top - Py_C_STACK_SIZE; + _tstate->c_stack_hard_limit = _tstate->c_stack_top - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); +#endif +} + /* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall() if the recursion_depth reaches recursion_limit. */ int _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) { -#ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - ++tstate->c_recursion_remaining; - _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); - return -1; + _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; + char here; + uintptr_t here_addr = (uintptr_t)&here; + assert(_tstate->c_stack_soft_limit != 0); + if (_tstate->c_stack_hard_limit == 0) { + _Py_InitializeRecursionLimits(tstate); + } + if (here_addr >= _tstate->c_stack_soft_limit) { + return 0; + } + assert(_tstate->c_stack_hard_limit != 0); + if (here_addr < _tstate->c_stack_hard_limit) { + /* Overflowing while handling an overflow. Give up. */ + int kbytes_used = (int)(_tstate->c_stack_top - here_addr)/1024; + char buffer[80]; + snprintf(buffer, 80, "Unrecoverable stack overflow (used %d kB)%s", kbytes_used, where); + Py_FatalError(buffer); } -#endif if (tstate->recursion_headroom) { - if (tstate->c_recursion_remaining < -50) { - /* Overflowing while handling an overflow. Give up. */ - Py_FatalError("Cannot recover from stack overflow."); - } + return 0; } else { - if (tstate->c_recursion_remaining <= 0) { - tstate->recursion_headroom++; - _PyErr_Format(tstate, PyExc_RecursionError, - "maximum recursion depth exceeded%s", - where); - tstate->recursion_headroom--; - ++tstate->c_recursion_remaining; - return -1; - } + int kbytes_used = (int)(_tstate->c_stack_top - here_addr)/1024; + tstate->recursion_headroom++; + _PyErr_Format(tstate, PyExc_RecursionError, + "Stack overflow (used %d kB)%s", + kbytes_used, + where); + tstate->recursion_headroom--; + return -1; } - return 0; } @@ -761,11 +831,6 @@ _PyObjectArray_Free(PyObject **array, PyObject **scratch) } -/* _PyEval_EvalFrameDefault() is a *big* function, - * so consume 3 units of C stack */ -#define PY_EVAL_C_STACK_UNITS 2 - - /* _PyEval_EvalFrameDefault is too large to optimize for speed with PGO on MSVC. */ #if (defined(_MSC_VER) && \ @@ -838,8 +903,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int frame->previous = &entry_frame; tstate->current_frame = frame; - tstate->c_recursion_remaining -= (PY_EVAL_C_STACK_UNITS - 1); - /* support for generator.throw() */ if (throwflag) { if (_Py_EnterRecursivePy(tstate)) { @@ -998,7 +1061,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(frame->owner == FRAME_OWNED_BY_INTERPRETER); /* Restore previous frame and exit */ tstate->current_frame = frame->previous; - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; return NULL; } @@ -1562,11 +1624,9 @@ clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) // _PyThreadState_PopFrame, since f_code is already cleared at that point: assert((PyObject **)frame + _PyFrame_GetCode(frame)->co_framesize == tstate->datastack_top); - tstate->c_recursion_remaining--; assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); _PyFrame_ClearExceptCode(frame); PyStackRef_CLEAR(frame->f_executable); - tstate->c_recursion_remaining++; _PyThreadState_PopFrame(tstate, frame); } @@ -1579,11 +1639,9 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) assert(tstate->exc_info == &gen->gi_exc_state); tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; - tstate->c_recursion_remaining--; assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); _PyFrame_ClearExceptCode(frame); _PyErr_ClearExcState(&gen->gi_exc_state); - tstate->c_recursion_remaining++; frame->previous = NULL; } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 5962e0ebd4f493..9520bc854dc831 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5426,14 +5426,13 @@ JUMP_TO_JUMP_TARGET(); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o); _PyStackRef arg = args[0]; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable_o), PyStackRef_AsPyObjectBorrow(arg)); stack_pointer = _PyFrame_GetStackPointer(frame); @@ -5813,7 +5812,7 @@ JUMP_TO_JUMP_TARGET(); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } @@ -5826,7 +5825,6 @@ } STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyStackRef_AsPyObjectBorrow(self_stackref), @@ -5984,13 +5982,12 @@ JUMP_TO_JUMP_TARGET(); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, self, NULL); stack_pointer = _PyFrame_GetStackPointer(frame); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 01fa857b96ac3b..268e8836994bc4 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -2222,7 +2222,7 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); @@ -2230,7 +2230,6 @@ STAT_INC(CALL, hit); PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable_o); _PyStackRef arg = args[0]; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable_o), PyStackRef_AsPyObjectBorrow(arg)); stack_pointer = _PyFrame_GetStackPointer(frame); @@ -3599,14 +3598,13 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); } STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, self, NULL); stack_pointer = _PyFrame_GetStackPointer(frame); @@ -3696,7 +3694,7 @@ JUMP_TO_PREDICTED(CALL); } // CPython promises to check all non-vectorcall function calls. - if (tstate->c_recursion_remaining <= 0) { + if (_Py_ReachedRecursionLimit(tstate)) { UPDATE_MISS_STATS(CALL); assert(_PyOpcode_Deopt[opcode] == (CALL)); JUMP_TO_PREDICTED(CALL); @@ -3711,7 +3709,6 @@ } STAT_INC(CALL, hit); PyCFunction cfunc = meth->ml_meth; - _Py_EnterRecursiveCallTstateUnchecked(tstate); _PyFrame_SetStackPointer(frame, stack_pointer); PyObject *res_o = _PyCFunction_TrampolineCall(cfunc, PyStackRef_AsPyObjectBorrow(self_stackref), @@ -7292,7 +7289,6 @@ /* Restore previous frame and return. */ tstate->current_frame = frame->previous; assert(!_PyErr_Occurred(tstate)); - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; PyObject *result = PyStackRef_AsPyObjectSteal(retval); stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); @@ -12081,7 +12077,6 @@ JUMP_TO_LABEL(error); if (frame->owner == FRAME_OWNED_BY_INTERPRETER) { /* Restore previous frame and exit */ tstate->current_frame = frame->previous; - tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; return NULL; } next_instr = frame->instr_ptr; diff --git a/Python/pystate.c b/Python/pystate.c index 24c7e290c50ec6..09b83cdeb1f42d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1490,10 +1490,9 @@ init_threadstate(_PyThreadStateImpl *_tstate, // thread_id and native_thread_id are set in bind_tstate(). - tstate->py_recursion_limit = interp->ceval.recursion_limit, - tstate->py_recursion_remaining = interp->ceval.recursion_limit, - tstate->c_recursion_remaining = Py_C_RECURSION_LIMIT; - + tstate->py_recursion_limit = interp->ceval.recursion_limit; + tstate->py_recursion_remaining = interp->ceval.recursion_limit; + tstate->c_recursion_remaining = 2; tstate->exc_info = &tstate->exc_state; // PyGILState_Release must not try to delete this thread state. @@ -1508,6 +1507,10 @@ init_threadstate(_PyThreadStateImpl *_tstate, tstate->previous_executor = NULL; tstate->dict_global_version = 0; + _tstate->c_stack_soft_limit = UINTPTR_MAX; + _tstate->c_stack_top = 0; + _tstate->c_stack_hard_limit = 0; + _tstate->asyncio_running_loop = NULL; _tstate->asyncio_running_task = NULL; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 945e267ef72c6f..36390dac6152f6 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1528,12 +1528,8 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp } #if defined(USE_STACKCHECK) -#if defined(WIN32) && defined(_MSC_VER) -/* Stack checking for Microsoft C */ - -#include -#include +/* Stack checking */ /* * Return non-zero when we run out of memory on the stack; zero otherwise. @@ -1541,27 +1537,10 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp int PyOS_CheckStack(void) { - __try { - /* alloca throws a stack overflow exception if there's - not enough space left on the stack */ - alloca(PYOS_STACK_MARGIN * sizeof(void*)); - return 0; - } __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ? - EXCEPTION_EXECUTE_HANDLER : - EXCEPTION_CONTINUE_SEARCH) { - int errcode = _resetstkoflw(); - if (errcode == 0) - { - Py_FatalError("Could not reset the stack!"); - } - } - return 1; + PyThreadState *tstate = _PyThreadState_GET(); + return _Py_ReachedRecursionLimit(tstate); } -#endif /* WIN32 && _MSC_VER */ - -/* Alternate implementations can be added here... */ - #endif /* USE_STACKCHECK */ /* Deprecated C API functions still provided for binary compatibility */ diff --git a/Python/symtable.c b/Python/symtable.c index 49bd01ba68ac9e..873576183314e6 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -406,7 +406,6 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, _PyFutureFeatures *future) asdl_stmt_seq *seq; Py_ssize_t i; PyThreadState *tstate; - int starting_recursion_depth; if (st == NULL) return NULL; @@ -423,11 +422,6 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, _PyFutureFeatures *future) _PySymtable_Free(st); return NULL; } - /* Be careful here to prevent overflow. */ - int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining; - starting_recursion_depth = recursion_depth; - st->recursion_depth = starting_recursion_depth; - st->recursion_limit = Py_C_RECURSION_LIMIT; /* Make the initial symbol information gathering pass */ @@ -469,14 +463,6 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, _PyFutureFeatures *future) _PySymtable_Free(st); return NULL; } - /* Check that the recursion depth counting balanced correctly */ - if (st->recursion_depth != starting_recursion_depth) { - PyErr_Format(PyExc_SystemError, - "symtable analysis recursion depth mismatch (before=%d, after=%d)", - starting_recursion_depth, st->recursion_depth); - _PySymtable_Free(st); - return NULL; - } /* Make the second symbol analysis pass */ if (symtable_analyze(st)) { #if _PY_DUMP_SYMTABLE @@ -1736,19 +1722,12 @@ symtable_enter_type_param_block(struct symtable *st, identifier name, } \ } while(0) -#define ENTER_RECURSIVE(ST) \ - do { \ - if (++(ST)->recursion_depth > (ST)->recursion_limit) { \ - PyErr_SetString(PyExc_RecursionError, \ - "maximum recursion depth exceeded during compilation"); \ - return 0; \ - } \ - } while(0) +#define ENTER_RECURSIVE() \ +if (Py_EnterRecursiveCall(" during compilation")) { \ + return 0; \ +} -#define LEAVE_RECURSIVE(ST) \ - do { \ - --(ST)->recursion_depth; \ - } while(0) +#define LEAVE_RECURSIVE() Py_LeaveRecursiveCall(); static int @@ -1823,7 +1802,7 @@ maybe_set_ste_coroutine_for_module(struct symtable *st, stmt_ty s) static int symtable_visit_stmt(struct symtable *st, stmt_ty s) { - ENTER_RECURSIVE(st); + ENTER_RECURSIVE(); switch (s->kind) { case FunctionDef_kind: { if (!symtable_add_def(st, s->v.FunctionDef.name, DEF_LOCAL, LOCATION(s))) @@ -2235,7 +2214,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, stmt, s->v.AsyncFor.orelse); break; } - LEAVE_RECURSIVE(st); + LEAVE_RECURSIVE(); return 1; } @@ -2358,7 +2337,7 @@ symtable_handle_namedexpr(struct symtable *st, expr_ty e) static int symtable_visit_expr(struct symtable *st, expr_ty e) { - ENTER_RECURSIVE(st); + ENTER_RECURSIVE(); switch (e->kind) { case NamedExpr_kind: if (!symtable_raise_if_annotation_block(st, "named expression", e)) { @@ -2529,7 +2508,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT_SEQ(st, expr, e->v.Tuple.elts); break; } - LEAVE_RECURSIVE(st); + LEAVE_RECURSIVE(); return 1; } @@ -2563,7 +2542,7 @@ symtable_visit_type_param_bound_or_default( static int symtable_visit_type_param(struct symtable *st, type_param_ty tp) { - ENTER_RECURSIVE(st); + ENTER_RECURSIVE(); switch(tp->kind) { case TypeVar_kind: if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp))) @@ -2612,14 +2591,14 @@ symtable_visit_type_param(struct symtable *st, type_param_ty tp) } break; } - LEAVE_RECURSIVE(st); + LEAVE_RECURSIVE(); return 1; } static int symtable_visit_pattern(struct symtable *st, pattern_ty p) { - ENTER_RECURSIVE(st); + ENTER_RECURSIVE(); switch (p->kind) { case MatchValue_kind: VISIT(st, expr, p->v.MatchValue.value); @@ -2668,7 +2647,7 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p) VISIT_SEQ(st, pattern, p->v.MatchOr.patterns); break; } - LEAVE_RECURSIVE(st); + LEAVE_RECURSIVE(); return 1; } diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 295bcc87b2cadf..10db9acbb362c8 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -653,7 +653,6 @@ def has_error_without_pop(op: parser.CodeDef) -> bool: "_PyUnicode_JoinArray", "_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY", "_Py_DECREF_NO_DEALLOC", - "_Py_EnterRecursiveCallTstateUnchecked", "_Py_ID", "_Py_IsImmortal", "_Py_LeaveRecursiveCallPy", @@ -673,6 +672,7 @@ def has_error_without_pop(op: parser.CodeDef) -> bool: "initial_temperature_backoff_counter", "JUMP_TO_LABEL", "restart_backoff_counter", + "_Py_ReachedRecursionLimit", ) def find_stmt_start(node: parser.CodeDef, idx: int) -> lexer.Token: diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py index a4951d05e80ebd..2be85a163b4043 100644 --- a/Tools/peg_generator/pegen/c_generator.py +++ b/Tools/peg_generator/pegen/c_generator.py @@ -44,7 +44,7 @@ # define MAXSTACK 4000 # endif #else -# define MAXSTACK 6000 +# define MAXSTACK 4000 #endif """ @@ -380,7 +380,7 @@ def __init__( self.cleanup_statements: List[str] = [] def add_level(self) -> None: - self.print("if (p->level++ == MAXSTACK) {") + self.print("if (p->level++ == MAXSTACK || _Py_ReachedRecursionLimitWithMargin(PyThreadState_Get(), 1)) {") with self.indent(): self.print("_Pypegen_stack_overflow(p);") self.print("}") From 3fa536f6f0d010a37dab1fe543b0175cf7f610b3 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 11:06:59 +0000 Subject: [PATCH 02/21] Use pthread_getattr_np to determine stack limits on systems supporting _GNU_SOURCE --- Python/ceval.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Python/ceval.c b/Python/ceval.c index 0459c57c4cbaed..087f93c07b433d 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -360,6 +360,21 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) _tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + PYOS_STACK_MARGIN_BYTES; _tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; #else +# if defined(_GNU_SOURCE) + size_t stack_size, guard_size; + void *stack_addr; + pthread_attr_t attr; + int err = pthread_getattr_np(pthread_self(), &attr); + err |= pthread_attr_getguardsize(&attr, &guard_size); + err |= pthread_attr_getstack(&attr, &stack_addr, &stack_size); + if (err == 0) { + uintptr_t base = ((uintptr_t)stack_addr) + guard_size; + _tstate->c_stack_top = base + stack_size; + _tstate->c_stack_soft_limit = base + PYOS_STACK_MARGIN_BYTES * 2; + _tstate->c_stack_hard_limit = base + PYOS_STACK_MARGIN_BYTES; + return; + } +# endif char here; uintptr_t here_addr = (uintptr_t)&here; _tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096); From 6823fee10c025de4e7f795fe88b41e865241877e Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 11:12:51 +0000 Subject: [PATCH 03/21] Add news --- .../2025-02-21-11-12-41.gh-issue-130396.SIenSP.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-11-12-41.gh-issue-130396.SIenSP.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-11-12-41.gh-issue-130396.SIenSP.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-11-12-41.gh-issue-130396.SIenSP.rst new file mode 100644 index 00000000000000..9dccf6260e0855 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-11-12-41.gh-issue-130396.SIenSP.rst @@ -0,0 +1,3 @@ +Use actual stack limits (from pthread_getattr_np) for linux, and other +systems with _GNU_SOURCE defined, when determining limits for C stack +protection. From ad4eb6eb5413f06dfd6a06050379fd76a1a3df73 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 12:10:21 +0000 Subject: [PATCH 04/21] Use config option --- Python/ceval.c | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 087f93c07b433d..639c4acf8f7677 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -360,7 +360,7 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) _tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + PYOS_STACK_MARGIN_BYTES; _tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; #else -# if defined(_GNU_SOURCE) +# if defined(HAVE_PTHREAD_GETATTR_NP) size_t stack_size, guard_size; void *stack_addr; pthread_attr_t attr; diff --git a/configure.ac b/configure.ac index 234ae90616af62..7ff0251b718386 100644 --- a/configure.ac +++ b/configure.ac @@ -5147,7 +5147,7 @@ AC_CHECK_FUNCS([ \ posix_spawn_file_actions_addclosefrom_np \ pread preadv preadv2 process_vm_readv \ pthread_cond_timedwait_relative_np pthread_condattr_setclock pthread_init \ - pthread_kill pthread_getname_np pthread_setname_np \ + pthread_kill pthread_getname_np pthread_setname_np pthread_getattr_np \ ptsname ptsname_r pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \ rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \ sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \ From 93a681a695755dd909c45c924bc8a67acb775c64 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 12:15:13 +0000 Subject: [PATCH 05/21] Manually update config --- configure | 6 ++++++ pyconfig.h.in | 3 +++ 2 files changed, 9 insertions(+) diff --git a/configure b/configure index 453b0123ded0a4..677d0e8840676f 100755 --- a/configure +++ b/configure @@ -19620,6 +19620,12 @@ if test "x$ac_cv_func_pthread_setname_np" = xyes then : printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "pthread_getattr_np" "ac_cv_func_pthread_getattr_np" +if test "x$ac_cv_func_pthread_getattr_np" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_GETATTR_NP 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "ptsname" "ac_cv_func_ptsname" if test "x$ac_cv_func_ptsname" = xyes diff --git a/pyconfig.h.in b/pyconfig.h.in index 4295b4f5ea5fbd..f12517301811dc 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -984,6 +984,9 @@ /* Defined for Solaris 2.6 bug in pthread header. */ #undef HAVE_PTHREAD_DESTRUCTOR +/* Define to 1 if you have the 'pthread_getattr_np' function. */ +#undef HAVE_PTHREAD_GETATTR_NP + /* Define to 1 if you have the 'pthread_getcpuclockid' function. */ #undef HAVE_PTHREAD_GETCPUCLOCKID From f6f68f6d50daac7e25e859a64b2e5e5256381383 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 13:40:10 +0000 Subject: [PATCH 06/21] Add some asserts and up limits --- Lib/test/list_tests.py | 2 +- Lib/test/support/__init__.py | 2 +- Lib/test/test_ast/test_ast.py | 2 +- Lib/test/test_compile.py | 4 ++-- Python/ceval.c | 7 +++++-- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index 4e63abfc3ce1b3..1465d78720396d 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -64,7 +64,7 @@ def test_repr(self): @skip_emscripten_stack_overflow() def test_repr_deep(self): a = self.type2test([]) - for i in range(100_000): + for i in range(150_000): a = self.type2test([a]) self.assertRaises(RecursionError, repr, a) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 88ac5a56ee928e..0127ab6888a1d3 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2628,7 +2628,7 @@ def adjust_int_max_str_digits(max_digits): def exceeds_recursion_limit(): """For recursion tests, easily exceeds default recursion limit.""" - return 100_000 + return 150_000 # Windows doesn't have os.uname() but it doesn't support s390x. diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index 1c202f82e941e8..e5798746a916e5 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -754,7 +754,7 @@ def next(self): @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_ast_recursion_limit(self): - crash_depth = 200_000 + crash_depth = 300_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 e0a33b8141c709..7d029e292416e4 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -714,8 +714,8 @@ def test_yet_more_evil_still_undecodable(self): def test_compiler_recursion_limit(self): # Compiler frames are small limit = 100 - fail_depth = limit * 1000 - crash_depth = limit * 2000 + fail_depth = limit * 1500 + crash_depth = limit * 3000 success_depth = limit def check_limit(prefix, repeated, mode="single"): diff --git a/Python/ceval.c b/Python/ceval.c index 639c4acf8f7677..4ca9d264223768 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -360,6 +360,8 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) _tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + PYOS_STACK_MARGIN_BYTES; _tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; #else + char here; + uintptr_t here_addr = (uintptr_t)&here; # if defined(HAVE_PTHREAD_GETATTR_NP) size_t stack_size, guard_size; void *stack_addr; @@ -367,16 +369,17 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) int err = pthread_getattr_np(pthread_self(), &attr); err |= pthread_attr_getguardsize(&attr, &guard_size); err |= pthread_attr_getstack(&attr, &stack_addr, &stack_size); + err |= pthread_attr_destroy(&attr); if (err == 0) { uintptr_t base = ((uintptr_t)stack_addr) + guard_size; _tstate->c_stack_top = base + stack_size; _tstate->c_stack_soft_limit = base + PYOS_STACK_MARGIN_BYTES * 2; _tstate->c_stack_hard_limit = base + PYOS_STACK_MARGIN_BYTES; + assert(_tstate->c_stack_soft_limit < here_addr); + assert(here_addr < _tstate->c_stack_top); return; } # endif - char here; - uintptr_t here_addr = (uintptr_t)&here; _tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096); _tstate->c_stack_soft_limit = _tstate->c_stack_top - Py_C_STACK_SIZE; _tstate->c_stack_hard_limit = _tstate->c_stack_top - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES); From e23fdeea2f3745613d850e6cea56e2eedbd8b45c Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 14:43:06 +0000 Subject: [PATCH 07/21] increase limits and use builtin functions to get stack pointer --- Include/internal/pycore_ceval.h | 16 ++++++++++++---- Lib/test/list_tests.py | 2 +- Lib/test/test_compile.py | 2 +- Lib/test/test_json/test_recursion.py | 2 +- Modules/_testinternalcapi.c | 3 +-- Python/ceval.c | 12 ++++-------- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index f9e6a99ce29d2b..8146074f6b48b1 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -193,9 +193,18 @@ extern void _PyEval_DeactivateOpCache(void); /* --- _Py_EnterRecursiveCall() ----------------------------------------- */ -static inline int _Py_MakeRecCheck(PyThreadState *tstate) { +static inline uintptr_t +_Py_get_machine_stack_pointer(void) { +#if defined(__GNUC__) || defined(__clang__) + return (uintptr_t)__builtin_frame_address(0); +#else char here; - uintptr_t here_addr = (uintptr_t)&here; + return (uintptr_t)&here; +#endif +} + +static inline int _Py_MakeRecCheck(PyThreadState *tstate) { + uintptr_t here_addr = _Py_get_machine_stack_pointer(); _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; return here_addr < _tstate->c_stack_soft_limit; } @@ -226,8 +235,7 @@ static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { PyAPI_FUNC(void) _Py_InitializeRecursionLimits(PyThreadState *tstate); static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate) { - char here; - uintptr_t here_addr = (uintptr_t)&here; + uintptr_t here_addr = _Py_get_machine_stack_pointer(); _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; if (here_addr > _tstate->c_stack_soft_limit) { return 0; diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index 1465d78720396d..68d6bad2094268 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -64,7 +64,7 @@ def test_repr(self): @skip_emscripten_stack_overflow() def test_repr_deep(self): a = self.type2test([]) - for i in range(150_000): + for i in range(200_000): a = self.type2test([a]) self.assertRaises(RecursionError, repr, a) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 7d029e292416e4..9802d1589522b8 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -715,7 +715,7 @@ def test_compiler_recursion_limit(self): # Compiler frames are small limit = 100 fail_depth = limit * 1500 - crash_depth = limit * 3000 + crash_depth = limit * 5000 success_depth = limit def check_limit(prefix, repeated, mode="single"): diff --git a/Lib/test/test_json/test_recursion.py b/Lib/test/test_json/test_recursion.py index 700821f8625834..673e3f1371e615 100644 --- a/Lib/test/test_json/test_recursion.py +++ b/Lib/test/test_json/test_recursion.py @@ -87,7 +87,7 @@ def test_highly_nested_objects_decoding(self): def test_highly_nested_objects_encoding(self): # See #12051 l, d = [], {} - for x in range(100000): + for x in range(200_000): l, d = [l], {'k':d} with self.assertRaises(RecursionError): with support.infinite_recursion(5000): diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 67cd96ac55e779..902984cb3db0ed 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -115,8 +115,7 @@ static PyObject* get_c_recursion_remaining(PyObject *self, PyObject *Py_UNUSED(args)) { PyThreadState *tstate = _PyThreadState_GET(); - char here; - uintptr_t here_addr = (uintptr_t)&here; + uintptr_t here_addr = _Py_get_machine_stack_pointer(); _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; int remaining = (int)((here_addr - _tstate->c_stack_soft_limit)/PYOS_STACK_MARGIN_BYTES * 50); return PyLong_FromLong(remaining); diff --git a/Python/ceval.c b/Python/ceval.c index 4ca9d264223768..a8db65ad913d43 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -307,8 +307,7 @@ Py_SetRecursionLimit(int new_limit) int _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count) { - char here; - uintptr_t here_addr = (uintptr_t)&here; + uintptr_t here_addr = _Py_get_machine_stack_pointer(); _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; if (here_addr > _tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES) { return 0; @@ -322,8 +321,7 @@ _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count) void _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) { - char here; - uintptr_t here_addr = (uintptr_t)&here; + uintptr_t here_addr = _Py_get_machine_stack_pointer(); _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; if (here_addr < _tstate->c_stack_hard_limit) { Py_FatalError("Unchecked stack overflow."); @@ -360,8 +358,7 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) _tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + PYOS_STACK_MARGIN_BYTES; _tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; #else - char here; - uintptr_t here_addr = (uintptr_t)&here; + uintptr_t here_addr = _Py_get_machine_stack_pointer(); # if defined(HAVE_PTHREAD_GETATTR_NP) size_t stack_size, guard_size; void *stack_addr; @@ -392,8 +389,7 @@ int _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) { _PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate; - char here; - uintptr_t here_addr = (uintptr_t)&here; + uintptr_t here_addr = _Py_get_machine_stack_pointer(); assert(_tstate->c_stack_soft_limit != 0); if (_tstate->c_stack_hard_limit == 0) { _Py_InitializeRecursionLimits(tstate); From 881fdede1a1f1012cd78baa39f0ee65b29c90e28 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 14:59:58 +0000 Subject: [PATCH 08/21] Increase test limits even more --- Lib/test/test_ast/test_ast.py | 2 +- Lib/test/test_json/test_recursion.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py index e5798746a916e5..6e1458facafc30 100644 --- a/Lib/test/test_ast/test_ast.py +++ b/Lib/test/test_ast/test_ast.py @@ -754,7 +754,7 @@ def next(self): @skip_wasi_stack_overflow() @skip_emscripten_stack_overflow() def test_ast_recursion_limit(self): - crash_depth = 300_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_json/test_recursion.py b/Lib/test/test_json/test_recursion.py index 673e3f1371e615..695eb584b68e14 100644 --- a/Lib/test/test_json/test_recursion.py +++ b/Lib/test/test_json/test_recursion.py @@ -74,13 +74,13 @@ def test_highly_nested_objects_decoding(self): # accelerations are used. See #12017 with self.assertRaises(RecursionError): with support.infinite_recursion(): - self.loads('{"a":' * 100000 + '1' + '}' * 100000) + self.loads('{"a":' * 200000 + '1' + '}' * 200000) with self.assertRaises(RecursionError): with support.infinite_recursion(): - self.loads('{"a":' * 100000 + '[1]' + '}' * 100000) + self.loads('{"a":' * 200000 + '[1]' + '}' * 200000) with self.assertRaises(RecursionError): with support.infinite_recursion(): - self.loads('[' * 100000 + '1' + ']' * 100000) + self.loads('[' * 200000 + '1' + ']' * 200000) @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() From d112618e0dfba37e283425463356cc31a9511405 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 15:20:25 +0000 Subject: [PATCH 09/21] Make stack check handle sanitizers better --- Include/pythonrun.h | 4 +++- Lib/test/test_functools.py | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 03b713beb8155f..78d555768f87cd 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -25,7 +25,9 @@ PyAPI_DATA(int) (*PyOS_InputHook)(void); * no two calls to check recursion depth are more than this far * apart. In practice, that means it must be larger than the C * stack consumption of PyEval_EvalDefault */ -#if defined(Py_DEBUG) && defined(WIN32) +#if defined(_Py_ADDRESS_SANITIZER) || defined(_Py_THREAD_SANITIZER) +# define PYOS_STACK_MARGIN 4096 +#elif defined(Py_DEBUG) && defined(WIN32) # define PYOS_STACK_MARGIN 3072 #else # define PYOS_STACK_MARGIN 2048 diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index b272631ae72c9d..d7404a81c234b3 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -404,6 +404,7 @@ def test_setstate_subclasses(self): self.assertEqual(r, ((1, 2), {})) self.assertIs(type(r[0]), tuple) + @support.skip_if_sanitizer("thread sanitizer crashes in __tsan::FuncEntry", thread=True) @support.skip_emscripten_stack_overflow() def test_recursive_pickle(self): with replaced_module('functools', self.module): From d215d21e6223f669f5455f0412ae5aea0842fdc2 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 15:33:19 +0000 Subject: [PATCH 10/21] Add stack protection to code gen --- Python/codegen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Python/codegen.c b/Python/codegen.c index cd77b34c06296b..7669cc5a65b7b6 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -4885,6 +4885,9 @@ codegen_with(compiler *c, stmt_ty s, int pos) static int codegen_visit_expr(compiler *c, expr_ty e) { + if (Py_EnterRecursiveCall(" during compilation")) { + return ERROR; + } location loc = LOC(e); switch (e->kind) { case NamedExpr_kind: From 4fae07e033780af38c9e8dd23764851d88eda280 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 15:54:56 +0000 Subject: [PATCH 11/21] Fix test_compile --- Lib/test/test_compile.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 9802d1589522b8..fedcd6a27047f0 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -714,19 +714,17 @@ def test_yet_more_evil_still_undecodable(self): def test_compiler_recursion_limit(self): # Compiler frames are small limit = 100 - fail_depth = limit * 1500 crash_depth = limit * 5000 success_depth = limit def check_limit(prefix, repeated, mode="single"): expect_ok = prefix + repeated * success_depth compile(expect_ok, '', mode) - for depth in (fail_depth, crash_depth): - broken = prefix + repeated * depth - details = "Compiling ({!r} + {!r} * {})".format( - prefix, repeated, depth) - with self.assertRaises(RecursionError, msg=details): - compile(broken, '', mode) + broken = prefix + repeated * crash_depth + details = "Compiling ({!r} + {!r} * {})".format( + prefix, repeated, crash_depth) + with self.assertRaises(RecursionError, msg=details): + compile(broken, '', mode) check_limit("a", "()") check_limit("a", ".b") From 20298c62fdd1b4b5ea79f39a5ec0a2331720d37c Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 16:21:22 +0000 Subject: [PATCH 12/21] Get a few more test passing on WASI --- Include/pythonrun.h | 3 +++ Lib/test/test_class.py | 5 +++-- Lib/test/test_dynamic.py | 2 +- Lib/test/test_patma.py | 1 + Python/ceval.c | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 78d555768f87cd..ef4b727442a935 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -29,6 +29,9 @@ PyAPI_DATA(int) (*PyOS_InputHook)(void); # define PYOS_STACK_MARGIN 4096 #elif defined(Py_DEBUG) && defined(WIN32) # define PYOS_STACK_MARGIN 3072 +#elif defined(__wasi__) + /* Web assembly has two stacks, so this isn't really a size */ +# define PYOS_STACK_MARGIN 500 #else # define PYOS_STACK_MARGIN 2048 #endif diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index 017aca3c82850f..4c12d43556fc2a 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -2,7 +2,7 @@ import unittest from test import support -from test.support import cpython_only, import_helper, script_helper, skip_emscripten_stack_overflow +from test.support import cpython_only, import_helper, script_helper testmeths = [ @@ -556,7 +556,8 @@ class Custom: self.assertFalse(hasattr(o, "__call__")) self.assertFalse(hasattr(c, "__call__")) - @skip_emscripten_stack_overflow() + @support.skip_emscripten_stack_overflow() + @support.skip_wasi_stack_overflow() def testSFBug532646(self): # Test for SF bug 532646 diff --git a/Lib/test/test_dynamic.py b/Lib/test/test_dynamic.py index 21bece26b893c6..2dcd40e416052a 100644 --- a/Lib/test/test_dynamic.py +++ b/Lib/test/test_dynamic.py @@ -134,7 +134,7 @@ def test_eval_gives_lambda_custom_globals(self): self.assertEqual(foo(), 7) - @unittest.skipIf(is_wasi and Py_DEBUG, "requires too much stack") + @unittest.skipIf(is_wasi, "requires too much stack") def test_load_global_specialization_failure_keeps_oparg(self): # https://github.com/python/cpython/issues/91625 class MyGlobals(dict): diff --git a/Lib/test/test_patma.py b/Lib/test/test_patma.py index dae6d898964cff..0bd57302e6169d 100644 --- a/Lib/test/test_patma.py +++ b/Lib/test/test_patma.py @@ -3498,6 +3498,7 @@ def f(command): # 0 self.assertListEqual(self._trace(f, 1), [1, 2, 3]) self.assertListEqual(self._trace(f, 0), [1, 2, 5, 6]) + @support.skip_wasi_stack_overflow() def test_parser_deeply_nested_patterns(self): # Deeply nested patterns can cause exponential backtracking when parsing. # See gh-93671 for more information. diff --git a/Python/ceval.c b/Python/ceval.c index a8db65ad913d43..8bbda3a0f201e8 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -338,7 +338,7 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) # define Py_C_STACK_SIZE 1600000 #elif defined(__wasi__) /* Web assembly has two stacks, so this isn't really the stack depth */ -# define Py_C_STACK_SIZE 100000 +# define Py_C_STACK_SIZE 80000 #elif defined(__hppa__) || defined(__powerpc64__) # define Py_C_STACK_SIZE 2000000 #else From ba9644340d3dca5ea707a51eb171b39c86555c4c Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 21 Feb 2025 16:39:01 +0000 Subject: [PATCH 13/21] Skip more WASI tests --- Lib/test/test_descr.py | 1 + Lib/test/test_isinstance.py | 2 ++ Lib/test/test_patma.py | 1 + 3 files changed, 4 insertions(+) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index f2f3d9469f8bab..be2cf9887f4226 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -3658,6 +3658,7 @@ def f(a): return a encoding='latin1', errors='replace') self.assertEqual(ba, b'abc\xbd?') + @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() def test_recursive_call(self): # Testing recursive __call__() by setting to instance of class... diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index 115e26c5541526..4f98cbb3762a98 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -263,12 +263,14 @@ def test_subclass_tuple(self): self.assertEqual(True, issubclass(int, (int, (float, int)))) self.assertEqual(True, issubclass(str, (str, (Child, str)))) + @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() def test_subclass_recursion_limit(self): # make sure that issubclass raises RecursionError before the C stack is # blown self.assertRaises(RecursionError, blowstack, issubclass, str, str) + @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() def test_isinstance_recursion_limit(self): # make sure that issubclass raises RecursionError before the C stack is diff --git a/Lib/test/test_patma.py b/Lib/test/test_patma.py index 0bd57302e6169d..5d0857b059ea23 100644 --- a/Lib/test/test_patma.py +++ b/Lib/test/test_patma.py @@ -6,6 +6,7 @@ import inspect import sys import unittest +from test import support @dataclasses.dataclass From b27414345dd5d431f758e69dfe63523807d31902 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Sat, 22 Feb 2025 13:03:54 +0000 Subject: [PATCH 14/21] Incorporate feedback from review and buildbots --- Include/internal/pycore_ceval.h | 2 +- Lib/test/test_builtin.py | 1 + Lib/test/test_call.py | 3 ++- Lib/test/test_descr.py | 1 + Lib/test/test_exceptions.py | 2 +- Python/ceval.c | 2 ++ 6 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 8146074f6b48b1..1a826796d83328 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -195,7 +195,7 @@ extern void _PyEval_DeactivateOpCache(void); static inline uintptr_t _Py_get_machine_stack_pointer(void) { -#if defined(__GNUC__) || defined(__clang__) +#if _Py__has_builtin(__builtin_frame_address) return (uintptr_t)__builtin_frame_address(0); #else char here; diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index d15964fe9dd88b..d707d9d2f20049 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -1052,6 +1052,7 @@ def test_filter_pickle(self): f2 = filter(filter_char, "abcdeabcde") self.check_iter_pickle(f1, list(f2), proto) + @support.skip_wasi_stack_overflow() @support.requires_resource('cpu') def test_filter_dealloc(self): # Tests recursive deallocation of nested filter objects using the diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 95eaf810eea091..f1b6c55999ebe0 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -1,6 +1,6 @@ import unittest from test.support import (cpython_only, is_wasi, requires_limited_api, Py_DEBUG, - set_recursion_limit, skip_on_s390x, exceeds_recursion_limit, skip_emscripten_stack_overflow, + set_recursion_limit, skip_on_s390x, exceeds_recursion_limit, skip_emscripten_stack_overflow, skip_wasi_stack_overflow, skip_if_sanitizer, import_helper) try: import _testcapi @@ -1040,6 +1040,7 @@ class TestRecursion(unittest.TestCase): @skip_if_sanitizer("requires deep stack", thread=True) @unittest.skipIf(_testcapi is None, "requires _testcapi") @skip_emscripten_stack_overflow() + @skip_wasi_stack_overflow() def test_super_deep(self): def recurse(n): diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index be2cf9887f4226..aa453e438facd5 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4519,6 +4519,7 @@ class Oops(object): o.whatever = Provoker(o) del o + @support.skip_wasi_stack_overflow() @support.requires_resource('cpu') def test_wrapper_segfault(self): # SF 927248: deeply nested wrappers could cause stack overflow diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index bd1053b67fde58..bf0bc53b634022 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1391,7 +1391,7 @@ def g(): self.assertIsInstance(exc, RecursionError, type(exc)) self.assertIn("maximum recursion depth exceeded", str(exc)) - + @support.skip_wasi_stack_overflow() @cpython_only @support.requires_resource('cpu') def test_trashcan_recursion(self): diff --git a/Python/ceval.c b/Python/ceval.c index 8bbda3a0f201e8..27cddcff6b12a5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -372,8 +372,10 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) _tstate->c_stack_top = base + stack_size; _tstate->c_stack_soft_limit = base + PYOS_STACK_MARGIN_BYTES * 2; _tstate->c_stack_hard_limit = base + PYOS_STACK_MARGIN_BYTES; +#ifndef _AIX assert(_tstate->c_stack_soft_limit < here_addr); assert(here_addr < _tstate->c_stack_top); +#endif return; } # endif From e4a7a3dafb6a0e169f76e469721b368d4647646f Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Sat, 22 Feb 2025 19:33:28 +0000 Subject: [PATCH 15/21] Address review comments --- Lib/test/test_compile.py | 3 +-- Lib/test/test_dynamic.py | 5 +++-- Lib/test/test_json/test_recursion.py | 7 ++++--- .../2025-02-21-11-12-41.gh-issue-130396.SIenSP.rst | 4 ++-- Python/ceval.c | 8 +++++--- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index fedcd6a27047f0..437b577f4d528a 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -721,8 +721,7 @@ def check_limit(prefix, repeated, mode="single"): expect_ok = prefix + repeated * success_depth compile(expect_ok, '', mode) broken = prefix + repeated * crash_depth - details = "Compiling ({!r} + {!r} * {})".format( - prefix, repeated, crash_depth) + details = f"Compiling ({prefix!r} + {repeated!r} * {crash_depth})" with self.assertRaises(RecursionError, msg=details): compile(broken, '', mode) diff --git a/Lib/test/test_dynamic.py b/Lib/test/test_dynamic.py index 2dcd40e416052a..19e779c46a2e84 100644 --- a/Lib/test/test_dynamic.py +++ b/Lib/test/test_dynamic.py @@ -4,7 +4,7 @@ import sys import unittest -from test.support import swap_item, swap_attr, is_wasi, Py_DEBUG +from test.support import swap_item, swap_attr, skip_wasi_stack_overflow, Py_DEBUG class RebindBuiltinsTests(unittest.TestCase): @@ -134,7 +134,8 @@ def test_eval_gives_lambda_custom_globals(self): self.assertEqual(foo(), 7) - @unittest.skipIf(is_wasi, "requires too much stack") + + @skip_wasi_stack_overflow() def test_load_global_specialization_failure_keeps_oparg(self): # https://github.com/python/cpython/issues/91625 class MyGlobals(dict): diff --git a/Lib/test/test_json/test_recursion.py b/Lib/test/test_json/test_recursion.py index 695eb584b68e14..d82093f3895167 100644 --- a/Lib/test/test_json/test_recursion.py +++ b/Lib/test/test_json/test_recursion.py @@ -70,17 +70,18 @@ def default(self, o): @support.skip_emscripten_stack_overflow() def test_highly_nested_objects_decoding(self): + very_deep = 200000 # test that loading highly-nested objects doesn't segfault when C # accelerations are used. See #12017 with self.assertRaises(RecursionError): with support.infinite_recursion(): - self.loads('{"a":' * 200000 + '1' + '}' * 200000) + self.loads('{"a":' * very_deep + '1' + '}' * very_deep) with self.assertRaises(RecursionError): with support.infinite_recursion(): - self.loads('{"a":' * 200000 + '[1]' + '}' * 200000) + self.loads('{"a":' * very_deep + '[1]' + '}' * very_deep) with self.assertRaises(RecursionError): with support.infinite_recursion(): - self.loads('[' * 200000 + '1' + ']' * 200000) + self.loads('[' * very_deep + '1' + ']' * very_deep) @support.skip_wasi_stack_overflow() @support.skip_emscripten_stack_overflow() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-11-12-41.gh-issue-130396.SIenSP.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-11-12-41.gh-issue-130396.SIenSP.rst index 9dccf6260e0855..49d1ce74d1cc8c 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-11-12-41.gh-issue-130396.SIenSP.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-21-11-12-41.gh-issue-130396.SIenSP.rst @@ -1,3 +1,3 @@ -Use actual stack limits (from pthread_getattr_np) for linux, and other -systems with _GNU_SOURCE defined, when determining limits for C stack +Use actual stack limits (from :manpage:`pthread_getattr_np(3)`) for linux, and other +systems with ``_GNU_SOURCE`` defined, when determining limits for C stack protection. diff --git a/Python/ceval.c b/Python/ceval.c index 27cddcff6b12a5..91e6f5ca3f898a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -364,9 +364,11 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) void *stack_addr; pthread_attr_t attr; int err = pthread_getattr_np(pthread_self(), &attr); - err |= pthread_attr_getguardsize(&attr, &guard_size); - err |= pthread_attr_getstack(&attr, &stack_addr, &stack_size); - err |= pthread_attr_destroy(&attr); + if (err == 0) { + err = pthread_attr_getguardsize(&attr, &guard_size); + err |= pthread_attr_getstack(&attr, &stack_addr, &stack_size); + err |= pthread_attr_destroy(&attr); + } if (err == 0) { uintptr_t base = ((uintptr_t)stack_addr) + guard_size; _tstate->c_stack_top = base + stack_size; From 7effdc5bc1929f0cb0253711ddef03fb1954df4f Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 24 Feb 2025 12:05:57 +0000 Subject: [PATCH 16/21] Try to avoid C compiler optimizing out local address --- Include/internal/pycore_ceval.h | 7 ++++++- Python/ceval.c | 2 -- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 1a826796d83328..474f8bdd6ee42c 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -193,13 +193,18 @@ extern void _PyEval_DeactivateOpCache(void); /* --- _Py_EnterRecursiveCall() ----------------------------------------- */ +static return_pointer_as_int(char* p) { + return (uintptr_t)p; +} + static inline uintptr_t _Py_get_machine_stack_pointer(void) { #if _Py__has_builtin(__builtin_frame_address) return (uintptr_t)__builtin_frame_address(0); #else char here; - return (uintptr_t)&here; + /* Avoid compiler warning about returning stack address */ + return return_pointer_as_int(&here); #endif } diff --git a/Python/ceval.c b/Python/ceval.c index 91e6f5ca3f898a..fc97aec1b03c17 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -374,10 +374,8 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) _tstate->c_stack_top = base + stack_size; _tstate->c_stack_soft_limit = base + PYOS_STACK_MARGIN_BYTES * 2; _tstate->c_stack_hard_limit = base + PYOS_STACK_MARGIN_BYTES; -#ifndef _AIX assert(_tstate->c_stack_soft_limit < here_addr); assert(here_addr < _tstate->c_stack_top); -#endif return; } # endif From 28ea7763f80f5436c908d6a2f49e359d5234cafa Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 24 Feb 2025 12:32:53 +0000 Subject: [PATCH 17/21] Fix typo --- Include/internal/pycore_ceval.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 474f8bdd6ee42c..d8df06ad5a7c78 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -193,7 +193,7 @@ extern void _PyEval_DeactivateOpCache(void); /* --- _Py_EnterRecursiveCall() ----------------------------------------- */ -static return_pointer_as_int(char* p) { +static uintptr_t return_pointer_as_int(char* p) { return (uintptr_t)p; } From 1d76b4859d827b5fe803ce309b0ecf3d7448f963 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 24 Feb 2025 12:37:39 +0000 Subject: [PATCH 18/21] Only define helper if needed --- Include/internal/pycore_ceval.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index d8df06ad5a7c78..13ab7d68663810 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -193,9 +193,11 @@ extern void _PyEval_DeactivateOpCache(void); /* --- _Py_EnterRecursiveCall() ----------------------------------------- */ +#if !_Py__has_builtin(__builtin_frame_address) static uintptr_t return_pointer_as_int(char* p) { return (uintptr_t)p; } +#endif static inline uintptr_t _Py_get_machine_stack_pointer(void) { From 415906c333488bac1a61d34cb90a61ee6983b993 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 24 Feb 2025 14:11:04 +0000 Subject: [PATCH 19/21] Revert to estimated stack size for AIX --- Python/ceval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index fc97aec1b03c17..7c9ac94878375f 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -342,7 +342,7 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate) #elif defined(__hppa__) || defined(__powerpc64__) # define Py_C_STACK_SIZE 2000000 #else -# define Py_C_STACK_SIZE 5000000 +# define Py_C_STACK_SIZE 4000000 #endif void @@ -359,7 +359,7 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate) _tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES; #else uintptr_t here_addr = _Py_get_machine_stack_pointer(); -# if defined(HAVE_PTHREAD_GETATTR_NP) +# if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(_AIX) size_t stack_size, guard_size; void *stack_addr; pthread_attr_t attr; From d13a059c344d6e01d5b7f7de8ab9fb37221089c3 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 24 Feb 2025 14:41:53 +0000 Subject: [PATCH 20/21] Try moving call to GC --- Lib/test/test_sys.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 39857445a02255..8cd3c7a73d0af9 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1090,6 +1090,10 @@ def test_getallocatedblocks(self): # about the underlying implementation: the function might # return 0 or something greater. self.assertGreaterEqual(a, 0) + gc.collect() + b = sys.getallocatedblocks() + self.assertLessEqual(b, a) + gc.collect() try: # While we could imagine a Python session where the number of # multiple buffer objects would exceed the sharing of references, @@ -1101,14 +1105,10 @@ def test_getallocatedblocks(self): # references, this can cause the total number of allocated # blocks to exceed the total number of references. if not support.Py_GIL_DISABLED: - self.assertLess(a, sys.gettotalrefcount()) + self.assertLess(b, sys.gettotalrefcount()) except AttributeError: # gettotalrefcount() not available pass - gc.collect() - b = sys.getallocatedblocks() - self.assertLessEqual(b, a) - gc.collect() c = sys.getallocatedblocks() self.assertIn(c, range(b - 50, b + 50)) From b3ccffcace0adcc58740f61c118e82cbf23af156 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Mon, 24 Feb 2025 14:43:35 +0000 Subject: [PATCH 21/21] Move gc.collect closer to count --- Lib/test/test_sys.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 8cd3c7a73d0af9..01872b91515c5c 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1093,7 +1093,6 @@ def test_getallocatedblocks(self): gc.collect() b = sys.getallocatedblocks() self.assertLessEqual(b, a) - gc.collect() try: # While we could imagine a Python session where the number of # multiple buffer objects would exceed the sharing of references, @@ -1109,6 +1108,7 @@ def test_getallocatedblocks(self): except AttributeError: # gettotalrefcount() not available pass + gc.collect() c = sys.getallocatedblocks() self.assertIn(c, range(b - 50, b + 50))