summaryrefslogtreecommitdiffstats
path: root/Modules/_testcapi
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_testcapi')
-rw-r--r--Modules/_testcapi/parts.h1
-rw-r--r--Modules/_testcapi/vectorcall_limited.c77
2 files changed, 78 insertions, 0 deletions
diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h
index e6d2ed2..4b672c9 100644
--- a/Modules/_testcapi/parts.h
+++ b/Modules/_testcapi/parts.h
@@ -1,4 +1,5 @@
#include "Python.h"
int _PyTestCapi_Init_Vectorcall(PyObject *module);
+int _PyTestCapi_Init_VectorcallLimited(PyObject *module);
int _PyTestCapi_Init_Heaptype(PyObject *module);
diff --git a/Modules/_testcapi/vectorcall_limited.c b/Modules/_testcapi/vectorcall_limited.c
new file mode 100644
index 0000000..63ea3b3
--- /dev/null
+++ b/Modules/_testcapi/vectorcall_limited.c
@@ -0,0 +1,77 @@
+#define Py_LIMITED_API 0x030c0000 // 3.12
+#include "parts.h"
+#include "structmember.h" // PyMemberDef
+
+/* Test Vectorcall in the limited API */
+
+static PyObject *
+LimitedVectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) {
+ return PyUnicode_FromString("tp_call called");
+}
+
+static PyObject *
+LimitedVectorCallClass_vectorcall(PyObject *callable,
+ PyObject *const *args,
+ size_t nargsf,
+ PyObject *kwnames) {
+ return PyUnicode_FromString("vectorcall called");
+}
+
+static PyObject *
+LimitedVectorCallClass_new(PyTypeObject *tp, PyTypeObject *a, PyTypeObject *kw)
+{
+ PyObject *self = ((allocfunc)PyType_GetSlot(tp, Py_tp_alloc))(tp, 0);
+ if (!self) {
+ return NULL;
+ }
+ *(vectorcallfunc*)((char*)self + sizeof(PyObject)) = (
+ LimitedVectorCallClass_vectorcall);
+ return self;
+}
+
+static PyMemberDef LimitedVectorCallClass_members[] = {
+ {"__vectorcalloffset__", T_PYSSIZET, sizeof(PyObject), READONLY},
+ {NULL}
+};
+
+static PyType_Slot LimitedVectorallClass_slots[] = {
+ {Py_tp_new, LimitedVectorCallClass_new},
+ {Py_tp_call, LimitedVectorCallClass_tpcall},
+ {Py_tp_members, LimitedVectorCallClass_members},
+ {0},
+};
+
+static PyType_Spec LimitedVectorCallClass_spec = {
+ .name = "_testcapi.LimitedVectorCallClass",
+ .basicsize = (int)(sizeof(PyObject) + sizeof(vectorcallfunc)),
+ .flags = Py_TPFLAGS_DEFAULT
+ | Py_TPFLAGS_HAVE_VECTORCALL
+ | Py_TPFLAGS_BASETYPE,
+ .slots = LimitedVectorallClass_slots,
+};
+
+static PyMethodDef TestMethods[] = {
+ /* Add module methods here.
+ * (Empty list left here as template/example, since using
+ * PyModule_AddFunctions isn't very common.)
+ */
+ {NULL},
+};
+
+int
+_PyTestCapi_Init_VectorcallLimited(PyObject *m) {
+ if (PyModule_AddFunctions(m, TestMethods) < 0) {
+ return -1;
+ }
+
+ PyObject *LimitedVectorCallClass = PyType_FromModuleAndSpec(
+ m, &LimitedVectorCallClass_spec, NULL);
+ if (!LimitedVectorCallClass) {
+ return -1;
+ }
+ if (PyModule_AddType(m, (PyTypeObject *)LimitedVectorCallClass) < 0) {
+ return -1;
+ }
+
+ return 0;
+}