Skip to content

Commit 96f7177

Browse files
[3.15] gh-140550: Enable limited C API tests on Free Threading in test_cext (GH-157493) (GH-157560)
Enable limited C API tests on Free Threading in test_cext and test_cppext: test Py_TARGET_ABI3T macro. * Convert test_cppext to PySlot API using PySlot_PTR_STATIC(). * Define Py_MOD_GIL_NOT_USED in test_cext and test_cppext. * Disable C++ test_virtual_object() if Py_TARGET_ABI3T is defined. (cherry picked from commit fb123c8) Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent 08fa744 commit 96f7177

5 files changed

Lines changed: 41 additions & 24 deletions

File tree

‎Lib/test/test_cext/__init__.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,9 @@ def run_cmd(operation, cmd):
110110

111111

112112
class TestPublicCAPI(BaseTests, unittest.TestCase):
113-
@support.requires_gil_enabled('incompatible with Free Threading')
114113
def test_build_limited(self):
115114
self.check_build('_test_limited_cext', limited=True)
116115

117-
@support.requires_gil_enabled('broken for now with Free Threading')
118116
def test_build_limited_c11(self):
119117
self.check_build('_test_limited_c11_cext', limited=True, std='c11')
120118

‎Lib/test/test_cext/extension.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ static PySlot _testcext_slots[] = {
131131
PySlot_STATIC_DATA(Py_mod_doc, (void*)(char*)_testcext_doc),
132132
PySlot_FUNC(Py_mod_exec, (void*)_testcext_exec),
133133
PySlot_STATIC_DATA(Py_mod_methods, _testcext_methods),
134+
PySlot_DATA(Py_mod_gil, Py_MOD_GIL_NOT_USED),
134135
PySlot_END,
135136
};
136137

‎Lib/test/test_cppext/__init__.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,9 @@ class TestPublicCAPI(BaseTests, unittest.TestCase):
102102
def test_build(self):
103103
self.check_build('_testcppext')
104104

105-
@support.requires_gil_enabled('incompatible with Free Threading')
106105
def test_build_limited_cpp03(self):
107106
self.check_build('_test_limited_cpp03ext', std='c++03', limited=True)
108107

109-
@support.requires_gil_enabled('incompatible with Free Threading')
110108
def test_build_limited(self):
111109
self.check_build('_testcppext_limited', limited=True)
112110

‎Lib/test/test_cppext/extension.cpp‎

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// gh-91321: Very basic C++ test extension to check that the Python C API is
1+
// gh-91321: Basic C++ test extension to check that the Python C API is
22
// compatible with C++ and does not emit C++ compiler warnings.
33
//
44
// The code is only built, not executed.
@@ -159,6 +159,8 @@ test_unicode(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
159159
Py_RETURN_NONE;
160160
}
161161

162+
// VirtualPyObject is incompatible with opaque PyObject
163+
#ifndef Py_TARGET_ABI3T
162164
/* Test a `new`-allocated object with a virtual method.
163165
* (https://github.com/python/cpython/issues/94731) */
164166

@@ -237,6 +239,8 @@ test_virtual_object(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
237239
}
238240
Py_RETURN_NONE;
239241
}
242+
#endif // Py_TARGET_ABI3T
243+
240244

241245
static PyObject *
242246
test_datetime(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
@@ -256,7 +260,9 @@ static PyMethodDef _testcppext_methods[] = {
256260
{"add", _testcppext_add, METH_VARARGS, _testcppext_add_doc},
257261
{"test_api_casts", test_api_casts, METH_NOARGS, _Py_NULL},
258262
{"test_unicode", test_unicode, METH_NOARGS, _Py_NULL},
263+
#ifndef Py_TARGET_ABI3T
259264
{"test_virtual_object", test_virtual_object, METH_NOARGS, _Py_NULL},
265+
#endif
260266
{"test_datetime", test_datetime, METH_NOARGS, _Py_NULL},
261267
// Note: _testcppext_exec currently runs all test functions directly.
262268
// When adding a new one, add a call there.
@@ -282,9 +288,11 @@ _testcppext_exec(PyObject *module)
282288
if (!result) return -1;
283289
Py_DECREF(result);
284290

291+
#ifndef Py_TARGET_ABI3T
285292
result = PyObject_CallMethod(module, "test_virtual_object", "");
286293
if (!result) return -1;
287294
Py_DECREF(result);
295+
#endif
288296

289297
result = PyObject_CallMethod(module, "test_datetime", "");
290298
if (!result) return -1;
@@ -297,6 +305,10 @@ _testcppext_exec(PyObject *module)
297305
return 0;
298306
}
299307

308+
309+
PyDoc_STRVAR(_testcppext_doc, "C++ test extension.");
310+
PyABIInfo_VAR(abi_info);
311+
300312
// Need to ignore "-Wpedantic" warnings; see VirtualPyObject_Slots above
301313
_Py_COMP_DIAG_PUSH
302314
#if defined(__GNUC__)
@@ -305,32 +317,38 @@ _Py_COMP_DIAG_PUSH
305317
#pragma clang diagnostic ignored "-Wpedantic"
306318
#endif
307319

308-
static PyModuleDef_Slot _testcppext_slots[] = {
309-
{Py_mod_exec, reinterpret_cast<void*>(_testcppext_exec)},
310-
{0, _Py_NULL}
320+
static PySlot _testcppext_slots[] = {
321+
PySlot_PTR_STATIC(Py_mod_abi, &abi_info),
322+
PySlot_PTR_STATIC(Py_mod_name, (void*)STR(MODULE_NAME)),
323+
PySlot_PTR_STATIC(Py_mod_doc, (void*)(char*)_testcppext_doc),
324+
PySlot_PTR_STATIC(Py_mod_exec, (void*)_testcppext_exec),
325+
PySlot_PTR_STATIC(Py_mod_methods, _testcppext_methods),
326+
PySlot_PTR_STATIC(Py_mod_gil, Py_MOD_GIL_NOT_USED),
327+
PySlot_END,
311328
};
312329

313330
_Py_COMP_DIAG_POP
314331

315-
PyDoc_STRVAR(_testcppext_doc, "C++ test extension.");
316-
317-
static struct PyModuleDef _testcppext_module = {
318-
PyModuleDef_HEAD_INIT, // m_base
319-
STR(MODULE_NAME), // m_name
320-
_testcppext_doc, // m_doc
321-
0, // m_size
322-
_testcppext_methods, // m_methods
323-
_testcppext_slots, // m_slots
324-
_Py_NULL, // m_traverse
325-
_Py_NULL, // m_clear
326-
_Py_NULL, // m_free
327-
};
328332

329-
#define _FUNC_NAME(NAME) PyInit_ ## NAME
333+
#define _FUNC_NAME(NAME) PyModExport_ ## NAME
330334
#define FUNC_NAME(NAME) _FUNC_NAME(NAME)
331335

332-
PyMODINIT_FUNC
336+
PyMODEXPORT_FUNC
333337
FUNC_NAME(MODULE_NAME)(void)
334338
{
335-
return PyModuleDef_Init(&_testcppext_module);
339+
return _testcppext_slots;
340+
}
341+
342+
// Also define the soft-deprecated entrypoint to ensure it isn't called
343+
344+
#define _INITFUNC_NAME(NAME) PyInit_ ## NAME
345+
#define INITFUNC_NAME(NAME) _INITFUNC_NAME(NAME)
346+
347+
PyMODINIT_FUNC
348+
INITFUNC_NAME(MODULE_NAME)(void)
349+
{
350+
PyErr_SetString(
351+
PyExc_AssertionError,
352+
"PyInit_* function called while a PyModExport_* one is available");
353+
return NULL;
336354
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Enable limited C API tests on Free Threading in test_cext and test_cppext:
2+
test the :c:macro:`Py_TARGET_ABI3T` macro. Patch by Victor Stinner.

0 commit comments

Comments
 (0)