]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-91079: Rename C_RECURSION_LIMIT to Py_C_RECURSION_LIMIT (#108507)
authorVictor Stinner <vstinner@python.org>
Fri, 8 Sep 2023 09:48:28 +0000 (11:48 +0200)
committerGitHub <noreply@github.com>
Fri, 8 Sep 2023 09:48:28 +0000 (09:48 +0000)
Symbols of the C API should be prefixed by "Py_" to avoid conflict
with existing names in 3rd party C extensions on "#include <Python.h>".

test.pythoninfo now logs Py_C_RECURSION_LIMIT constant and other
_testcapi and _testinternalcapi constants.

17 files changed:
Include/cpython/pystate.h
Lib/test/list_tests.py
Lib/test/mapping_tests.py
Lib/test/pythoninfo.py
Lib/test/support/__init__.py
Lib/test/test_compile.py
Lib/test/test_dict.py
Lib/test/test_dictviews.py
Lib/test/test_exception_group.py
Modules/_testcapimodule.c
Modules/_testinternalcapi.c
Parser/asdl_c.py
Python/Python-ast.c
Python/ast.c
Python/ast_opt.c
Python/pystate.c
Python/symtable.c

index fc5f58db86dbe87d06a7fe855edb9d301b15c45c..e1a15cddd3d7230473f294b1d2229512975e7f13 100644 (file)
@@ -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
index b1ef332522d2ce5cfefb1fb3638d7c326ea77f5c..d9ab21d4941cdb9b75440917746ef7e66dd21a58 100644 (file)
@@ -6,7 +6,7 @@ import sys
 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):
@@ -61,7 +61,7 @@ class CommonTest(seq_tests.CommonTest):
 
     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)
 
index 5492bbf86d1f879fba9000a58d36d085e0a2f7cb..b3e4192e65d95732576a712ffd41dd46f9a00211 100644 (file)
@@ -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):
@@ -625,7 +625,7 @@ class TestHashMappingProtocol(TestMappingProtocol):
 
     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
index c628833478044e948a24e1f38b0f0fd3ab5089bb..b25def78e42be45664e75988d5dc976bddb5009d 100644 (file)
@@ -665,6 +665,22 @@ 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:
@@ -672,6 +688,12 @@ def collect_testcapi(info_add):
 
     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:
@@ -907,6 +929,7 @@ def collect_info(info):
         collect_sys,
         collect_sysconfig,
         collect_testcapi,
+        collect_testinternalcapi,
         collect_time,
         collect_tkinter,
         collect_windows,
index 38ad965e155302759b4facf52c97e3f581202423..84b74ee2c298e937e3344f6b47e9244d1ec086eb 100644 (file)
@@ -60,7 +60,7 @@ __all__ = [
     "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",
     ]
 
@@ -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',
index de513daf825d811b6e76d62905dfb8ec3c7c7383..28b2c4686bbc89550c91e2817ea864ff7abb4831 100644 (file)
@@ -11,7 +11,7 @@ import textwrap
 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):
@@ -111,7 +111,7 @@ class TestSpecifics(unittest.TestCase):
 
     @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('''
@@ -557,12 +557,12 @@ class TestSpecifics(unittest.TestCase):
     @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
index eab64b4f9106c1206e1c5935d356a26a13c0f968..620d0ca4f4c2dae65de4a96584198d3d2b6b35bd 100644 (file)
@@ -8,7 +8,7 @@ import sys
 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):
@@ -596,7 +596,7 @@ class DictTest(unittest.TestCase):
 
     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)
 
index 2bd9d6eef8cfc617407932faf6228b478caa6f77..34918585513846d7bd51f4cc78c853ab8ddf79c2 100644 (file)
@@ -3,7 +3,7 @@ import copy
 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):
 
@@ -280,7 +280,7 @@ class DictSetTest(unittest.TestCase):
 
     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)
 
index a02d54da35e948ab54932dd6899610058e88a8c8..20122679223843151252b18998619f8394f71433 100644 (file)
@@ -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):
@@ -460,7 +460,7 @@ class ExceptionGroupSplitTests(ExceptionGroupTestBase):
 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
 
index 9bd963baf066a4e2b906467fc030f5de8099fa7a..85d8401435e1b5aa4ec16ce0038776e200e33c74 100644 (file)
@@ -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);
index b6792e38fa98c26091c251d8c6cd1de1798eadf4..922672d1a9f9158980f3d2d1854637307f2ad35e 100644 (file)
@@ -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;
index ca259c8cd1f3ba4ea36aaedf23fd8c7a6925acce..f61099b97055adbf958e3aab3d2c21ec9717d7f7 100755 (executable)
@@ -1401,8 +1401,8 @@ PyObject* PyAST_mod2obj(mod_ty t)
     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;
 
index 77b23f7c5edf2376768564edf3c399faded8a73b..a197d44868b5aa3eaef495c86898944c44c7863e 100644 (file)
@@ -13081,8 +13081,8 @@ PyObject* PyAST_mod2obj(mod_ty t)
     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;
 
index 74c97f948d15e63d5b02fade7b09d7188218adc4..21cb38f8cbfb65be6800b53fc69ff4fc32878192 100644 (file)
@@ -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:
index 82e7559e5b629a670ff47e6fa7fe4ec34e37dea3..41f48eba08afc41d414c92788721ef57ca481683 100644 (file)
@@ -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());
index ed14f82688f401f3aa550c72950b165f64f831da..89275fd7e025ca39afac2ea6419d97614050faa9 100644 (file)
@@ -1334,7 +1334,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;
 
index f157d4c170314a2bff147ad8e09675efe4e00b97..217e6f59a6148418f548d9d41abf095351508269 100644 (file)
@@ -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)) {