diff options
Diffstat (limited to 'Modules/_testcapi')
-rw-r--r-- | Modules/_testcapi/parts.h | 1 | ||||
-rw-r--r-- | Modules/_testcapi/vectorcall_limited.c | 77 |
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; +} |