From a11419e220b9a8bca50c50b80fd24d09fa8bf408 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Aug 2026 21:28:18 +0200 Subject: [PATCH 1/3] gh-155561: Use PySlot API in Modules/_testlimitedcapi.c --- Modules/_testlimitedcapi.c | 109 +++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 60 deletions(-) diff --git a/Modules/_testlimitedcapi.c b/Modules/_testlimitedcapi.c index de8bed77d7d327..6841561d671093 100644 --- a/Modules/_testlimitedcapi.c +++ b/Modules/_testlimitedcapi.c @@ -2,122 +2,111 @@ * Test the limited C API. * * The 'test_*' functions exported by this module are run as part of the - * standard Python regression test, via Lib/test/test_capi.py. + * standard Python regression test, via Lib/test/test_capi/test_misc.py. */ -#include "pyconfig.h" // Py_GIL_DISABLED - -#ifdef Py_GIL_DISABLED - // Cannot test the limited C API -#else - // Use the oldest limited C API version -# define Py_LIMITED_API 0x03020000 -#endif +// Need limited C API version 3.15 for PySlot +#define Py_LIMITED_API 0x030f0000 #include "_testlimitedcapi/parts.h" -static PyMethodDef TestMethods[] = { - {NULL, NULL} /* sentinel */ -}; - -static struct PyModuleDef _testlimitedcapimodule = { - PyModuleDef_HEAD_INIT, - .m_name = "_testlimitedcapi", - .m_size = 0, - .m_methods = TestMethods, -}; - -PyMODINIT_FUNC -PyInit__testlimitedcapi(void) +static int +module_exec(PyObject *mod) { - PyObject *mod = PyModule_Create(&_testlimitedcapimodule); - if (mod == NULL) { - return NULL; - } -#ifdef Py_GIL_DISABLED - PyUnstable_Module_SetGIL(mod, Py_MOD_GIL_NOT_USED); -#endif - if (_PyTestLimitedCAPI_Init_Abstract(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_ByteArray(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Bytes(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Capsule(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Codec(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Complex(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Dict(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Eval(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Float(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_HeaptypeRelative(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Import(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_List(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Long(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Object(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_PyOS(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Set(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Slots(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Sys(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_ThreadState(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Tuple(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Unicode(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_VectorcallLimited(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Version(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_File(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Weakref(mod) < 0) { - return NULL; + return -1; } if (_PyTestLimitedCAPI_Init_Run(mod) < 0) { - return NULL; + return -1; } - if (_PyTestLimitedCAPI_Init_Type(mod) < 0) { - return NULL; - } - return mod; + return 0; +} + +PyABIInfo_VAR(abi_info); + +static PySlot _testlimitedcapimodule_slots[] = { + PySlot_DATA(Py_mod_abi, &abi_info), + PySlot_STATIC_DATA(Py_mod_name, "_testlimitedcapi"), + PySlot_SIZE(Py_mod_state_size, 0), + PySlot_FUNC(Py_mod_exec, module_exec), + PySlot_SIZE(Py_mod_gil, Py_MOD_GIL_NOT_USED), + PySlot_END +}; + +PyMODEXPORT_FUNC +PyModExport__testlimitedcapi(void) +{ + return _testlimitedcapimodule_slots; } From 27c121d7cef39b4d77cf54caf2cc9bc21976d494 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Aug 2026 14:14:02 +0200 Subject: [PATCH 2/3] Add missing _PyTestLimitedCAPI_Init_Type() call --- Modules/_testlimitedcapi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/_testlimitedcapi.c b/Modules/_testlimitedcapi.c index 6841561d671093..e9c3e00d7f6daa 100644 --- a/Modules/_testlimitedcapi.c +++ b/Modules/_testlimitedcapi.c @@ -91,6 +91,9 @@ module_exec(PyObject *mod) if (_PyTestLimitedCAPI_Init_Run(mod) < 0) { return -1; } + if (_PyTestLimitedCAPI_Init_Type(mod) < 0) { + return -1; + } return 0; } From bca539b9f2d055dc3e50090fd829cc905e7c3403 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Fri, 14 Aug 2026 16:46:13 +0200 Subject: [PATCH 3/3] Use multi-phase init, but still with a PyModuleDef --- Modules/_testlimitedcapi.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Modules/_testlimitedcapi.c b/Modules/_testlimitedcapi.c index e9c3e00d7f6daa..bcaf2108d6b284 100644 --- a/Modules/_testlimitedcapi.c +++ b/Modules/_testlimitedcapi.c @@ -99,17 +99,20 @@ module_exec(PyObject *mod) PyABIInfo_VAR(abi_info); -static PySlot _testlimitedcapimodule_slots[] = { - PySlot_DATA(Py_mod_abi, &abi_info), - PySlot_STATIC_DATA(Py_mod_name, "_testlimitedcapi"), - PySlot_SIZE(Py_mod_state_size, 0), - PySlot_FUNC(Py_mod_exec, module_exec), - PySlot_SIZE(Py_mod_gil, Py_MOD_GIL_NOT_USED), - PySlot_END +static struct PyModuleDef _testlimitedcapimodule_def = { + PyModuleDef_HEAD_INIT, + .m_name = "_testlimitedcapi", + .m_size = 0, + .m_slots = (PyModuleDef_Slot[]){ + {Py_mod_abi, &abi_info}, + {Py_mod_exec, module_exec}, + {Py_mod_gil, Py_MOD_GIL_NOT_USED}, + {0} + } }; -PyMODEXPORT_FUNC -PyModExport__testlimitedcapi(void) +PyMODINIT_FUNC +PyInit__testlimitedcapi(void) { - return _testlimitedcapimodule_slots; + return PyModuleDef_Init(&_testlimitedcapimodule_def); }