Skip to content

GH-91079: Rename C_RECURSION_LIMIT to Py_C_RECURSION_LIMIT #108507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions Include/cpython/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,18 +194,17 @@ struct _ts {

};

/* WASI has limited call stack. Python's recursion limit depends on code
layout, optimization, and WASI runtime. Wasmtime can handle about 700
recursions, sometimes less. 500 is a more conservative limit. */
#ifndef C_RECURSION_LIMIT
# ifdef __wasi__
# define C_RECURSION_LIMIT 500
# else
// This value is duplicated in Lib/test/support/__init__.py
# define C_RECURSION_LIMIT 1500
# endif
#ifdef __wasi__
// WASI has limited call stack. Python's recursion limit depends on code
// layout, optimization, and WASI runtime. Wasmtime can handle about 700
// recursions, sometimes less. 500 is a more conservative limit.
# define Py_C_RECURSION_LIMIT 500
#else
// This value is duplicated in Lib/test/support/__init__.py
# define Py_C_RECURSION_LIMIT 1500
#endif


/* other API */

/* Similar to PyThreadState_Get(), but don't issue a fatal error
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/list_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from functools import cmp_to_key

from test import seq_tests
from test.support import ALWAYS_EQ, NEVER_EQ, C_RECURSION_LIMIT
from test.support import ALWAYS_EQ, NEVER_EQ, Py_C_RECURSION_LIMIT


class CommonTest(seq_tests.CommonTest):
Expand Down Expand Up @@ -61,7 +61,7 @@ def test_repr(self):

def test_repr_deep(self):
a = self.type2test([])
for i in range(C_RECURSION_LIMIT + 1):
for i in range(Py_C_RECURSION_LIMIT + 1):
a = self.type2test([a])
self.assertRaises(RecursionError, repr, a)

Expand Down
4 changes: 2 additions & 2 deletions Lib/test/mapping_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import unittest
import collections
import sys
from test.support import C_RECURSION_LIMIT
from test.support import Py_C_RECURSION_LIMIT


class BasicTestMappingProtocol(unittest.TestCase):
Expand Down Expand Up @@ -625,7 +625,7 @@ def __repr__(self):

def test_repr_deep(self):
d = self._empty_mapping()
for i in range(C_RECURSION_LIMIT + 1):
for i in range(Py_C_RECURSION_LIMIT + 1):
d0 = d
d = self._empty_mapping()
d[1] = d0
Expand Down
23 changes: 23 additions & 0 deletions Lib/test/pythoninfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,13 +665,35 @@ def collect_decimal(info_add):


def collect_testcapi(info_add):
try:
import _testcapi
except ImportError:
return

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
):
copy_attr(info_add, f'_testcapi.{name}', _testcapi, name)


def collect_testinternalcapi(info_add):
try:
import _testinternalcapi
except ImportError:
return

call_func(info_add, 'pymem.allocator', _testinternalcapi, 'pymem_getallocatorsname')

for name in (
'SIZEOF_PYGC_HEAD',
'SIZEOF_PYOBJECT',
):
copy_attr(info_add, f'_testinternalcapi.{name}', _testinternalcapi, name)


def collect_resource(info_add):
try:
Expand Down Expand Up @@ -907,6 +929,7 @@ def collect_info(info):
collect_sys,
collect_sysconfig,
collect_testcapi,
collect_testinternalcapi,
collect_time,
collect_tkinter,
collect_windows,
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,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", "C_RECURSION_LIMIT",
"Py_DEBUG", "EXCEEDS_RECURSION_LIMIT", "Py_C_RECURSION_LIMIT",
"skip_on_s390x",
]

Expand Down Expand Up @@ -2531,7 +2531,7 @@ def adjust_int_max_str_digits(max_digits):
EXCEEDS_RECURSION_LIMIT = 5000

# The default C recursion limit (from Include/cpython/pystate.h).
C_RECURSION_LIMIT = 1500
Py_C_RECURSION_LIMIT = 1500

#Windows doesn't have os.uname() but it doesn't support s390x.
skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == 's390x',
Expand Down
12 changes: 6 additions & 6 deletions Lib/test/test_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import warnings
from test import support
from test.support import (script_helper, requires_debug_ranges,
requires_specialization, C_RECURSION_LIMIT)
requires_specialization, Py_C_RECURSION_LIMIT)
from test.support.os_helper import FakePath

class TestSpecifics(unittest.TestCase):
Expand Down Expand Up @@ -111,7 +111,7 @@ def __getitem__(self, key):

@unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI")
def test_extended_arg(self):
repeat = int(C_RECURSION_LIMIT * 0.9)
repeat = int(Py_C_RECURSION_LIMIT * 0.9)
longexpr = 'x = x or ' + '-x' * repeat
g = {}
code = textwrap.dedent('''
Expand Down Expand Up @@ -557,12 +557,12 @@ def test_yet_more_evil_still_undecodable(self):
@support.cpython_only
@unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI")
def test_compiler_recursion_limit(self):
# Expected limit is C_RECURSION_LIMIT * 2
# Expected limit is Py_C_RECURSION_LIMIT * 2
# Duplicating the limit here is a little ugly.
# Perhaps it should be exposed somewhere...
fail_depth = C_RECURSION_LIMIT * 2 + 1
crash_depth = C_RECURSION_LIMIT * 100
success_depth = int(C_RECURSION_LIMIT * 1.8)
fail_depth = Py_C_RECURSION_LIMIT * 2 + 1
crash_depth = Py_C_RECURSION_LIMIT * 100
success_depth = int(Py_C_RECURSION_LIMIT * 1.8)

def check_limit(prefix, repeated, mode="single"):
expect_ok = prefix + repeated * success_depth
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import unittest
import weakref
from test import support
from test.support import import_helper, C_RECURSION_LIMIT
from test.support import import_helper, Py_C_RECURSION_LIMIT


class DictTest(unittest.TestCase):
Expand Down Expand Up @@ -596,7 +596,7 @@ def __repr__(self):

def test_repr_deep(self):
d = {}
for i in range(C_RECURSION_LIMIT + 1):
for i in range(Py_C_RECURSION_LIMIT + 1):
d = {1: d}
self.assertRaises(RecursionError, repr, d)

Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_dictviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pickle
import sys
import unittest
from test.support import C_RECURSION_LIMIT
from test.support import Py_C_RECURSION_LIMIT

class DictSetTest(unittest.TestCase):

Expand Down Expand Up @@ -280,7 +280,7 @@ def test_recursive_repr(self):

def test_deeply_nested_repr(self):
d = {}
for i in range(C_RECURSION_LIMIT//2 + 100):
for i in range(Py_C_RECURSION_LIMIT//2 + 100):
d = {42: d.values()}
self.assertRaises(RecursionError, repr, d)

Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_exception_group.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import collections.abc
import types
import unittest
from test.support import C_RECURSION_LIMIT
from test.support import Py_C_RECURSION_LIMIT

class TestExceptionGroupTypeHierarchy(unittest.TestCase):
def test_exception_group_types(self):
Expand Down Expand Up @@ -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(C_RECURSION_LIMIT + 1):
for i in range(Py_C_RECURSION_LIMIT + 1):
e = ExceptionGroup('eg', [e])
return e

Expand Down
1 change: 1 addition & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3922,6 +3922,7 @@ PyInit__testcapi(void)
PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type);

PyModule_AddIntConstant(m, "the_number_three", 3);
PyModule_AddIntMacro(m, Py_C_RECURSION_LIMIT);

TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
Py_INCREF(TestError);
Expand Down
5 changes: 5 additions & 0 deletions Modules/_testinternalcapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1552,6 +1552,11 @@ module_exec(PyObject *module)
return 1;
}

if (PyModule_Add(module, "SIZEOF_PYOBJECT",
PyLong_FromSsize_t(sizeof(PyObject))) < 0) {
return 1;
}

if (PyModule_Add(module, "SIZEOF_TIME_T",
PyLong_FromSsize_t(sizeof(time_t))) < 0) {
return 1;
Expand Down
4 changes: 2 additions & 2 deletions Parser/asdl_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -1401,8 +1401,8 @@ class PartingShots(StaticVisitor):
if (!tstate) {
return 0;
}
state->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE;
int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining;
state->recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE;
int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining;
starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE;
state->recursion_depth = starting_recursion_depth;

Expand Down
4 changes: 2 additions & 2 deletions Python/Python-ast.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Python/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -1046,10 +1046,10 @@ _PyAST_Validate(mod_ty mod)
return 0;
}
/* Be careful here to prevent overflow. */
int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining;
int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining;
starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE;
state.recursion_depth = starting_recursion_depth;
state.recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE;
state.recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE;

switch (mod->kind) {
case Module_kind:
Expand Down
4 changes: 2 additions & 2 deletions Python/ast_opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1130,10 +1130,10 @@ _PyAST_Optimize(mod_ty mod, PyArena *arena, int optimize, int ff_features)
return 0;
}
/* Be careful here to prevent overflow. */
int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining;
int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining;
starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE;
state.recursion_depth = starting_recursion_depth;
state.recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE;
state.recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE;

int ret = astfold_mod(mod, arena, &state);
assert(ret || PyErr_Occurred());
Expand Down
2 changes: 1 addition & 1 deletion Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1333,7 +1333,7 @@ init_threadstate(PyThreadState *tstate,

tstate->py_recursion_limit = interp->ceval.recursion_limit,
tstate->py_recursion_remaining = interp->ceval.recursion_limit,
tstate->c_recursion_remaining = C_RECURSION_LIMIT;
tstate->c_recursion_remaining = Py_C_RECURSION_LIMIT;

tstate->exc_info = &tstate->exc_state;

Expand Down
4 changes: 2 additions & 2 deletions Python/symtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,10 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future)
return NULL;
}
/* Be careful here to prevent overflow. */
int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining;
int recursion_depth = Py_C_RECURSION_LIMIT - tstate->c_recursion_remaining;
starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE;
st->recursion_depth = starting_recursion_depth;
st->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE;
st->recursion_limit = Py_C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE;

/* Make the initial symbol information gathering pass */
if (!symtable_enter_block(st, &_Py_ID(top), ModuleBlock, (void *)mod, 0, 0, 0, 0)) {
Expand Down