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
241245static PyObject *
242246test_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
333337FUNC_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}
0 commit comments