aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_cext/extension.c
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_cext/extension.c')
-rw-r--r--Lib/test/test_cext/extension.c51
1 files changed, 47 insertions, 4 deletions
diff --git a/Lib/test/test_cext/extension.c b/Lib/test/test_cext/extension.c
index 64629c5a6da..73fc67ae59d 100644
--- a/Lib/test/test_cext/extension.c
+++ b/Lib/test/test_cext/extension.c
@@ -1,11 +1,31 @@
// gh-116869: Basic C test extension to check that the Python C API
// does not emit C compiler warnings.
+//
+// Test also the internal C API if the TEST_INTERNAL_C_API macro is defined.
// Always enable assertions
#undef NDEBUG
+#ifdef TEST_INTERNAL_C_API
+# define Py_BUILD_CORE_MODULE 1
+#endif
+
#include "Python.h"
+#ifdef TEST_INTERNAL_C_API
+ // gh-135906: Check for compiler warnings in the internal C API.
+ // - Cython uses pycore_frame.h.
+ // - greenlet uses pycore_frame.h, pycore_interpframe_structs.h and
+ // pycore_interpframe.h.
+# include "internal/pycore_frame.h"
+# include "internal/pycore_gc.h"
+# include "internal/pycore_interp.h"
+# include "internal/pycore_interpframe.h"
+# include "internal/pycore_interpframe_structs.h"
+# include "internal/pycore_object.h"
+# include "internal/pycore_pystate.h"
+#endif
+
#ifndef MODULE_NAME
# error "MODULE_NAME macro must be defined"
#endif
@@ -58,6 +78,9 @@ _testcext_exec(
return 0;
}
+#define _FUNC_NAME(NAME) PyInit_ ## NAME
+#define FUNC_NAME(NAME) _FUNC_NAME(NAME)
+
// Converting from function pointer to void* has undefined behavior, but
// works on all known platforms, and CPython's module and type slots currently
// need it.
@@ -76,9 +99,10 @@ static PyModuleDef_Slot _testcext_slots[] = {
_Py_COMP_DIAG_POP
-
PyDoc_STRVAR(_testcext_doc, "C test extension.");
+#ifndef _Py_OPAQUE_PYOBJECT
+
static struct PyModuleDef _testcext_module = {
PyModuleDef_HEAD_INIT, // m_base
STR(MODULE_NAME), // m_name
@@ -92,11 +116,30 @@ static struct PyModuleDef _testcext_module = {
};
-#define _FUNC_NAME(NAME) PyInit_ ## NAME
-#define FUNC_NAME(NAME) _FUNC_NAME(NAME)
-
PyMODINIT_FUNC
FUNC_NAME(MODULE_NAME)(void)
{
return PyModuleDef_Init(&_testcext_module);
}
+
+#else // _Py_OPAQUE_PYOBJECT
+
+// Opaque PyObject means that PyModuleDef is also opaque and cannot be
+// declared statically. See PEP 793.
+// So, this part of module creation is split into a separate source file
+// which uses non-limited API.
+
+// (repeated definition to avoid creating a header)
+extern PyObject *testcext_create_moduledef(
+ const char *name, const char *doc,
+ PyMethodDef *methods, PyModuleDef_Slot *slots);
+
+
+PyMODINIT_FUNC
+FUNC_NAME(MODULE_NAME)(void)
+{
+ return testcext_create_moduledef(
+ STR(MODULE_NAME), _testcext_doc, _testcext_methods, _testcext_slots);
+}
+
+#endif // _Py_OPAQUE_PYOBJECT