summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.pre.in2
-rw-r--r--Modules/Setup.stdlib.in2
-rw-r--r--Modules/_testcapi/README.txt3
-rw-r--r--Modules/_testcapi/parts.h3
-rw-r--r--Modules/_testcapi/vectorcall.c270
-rw-r--r--Modules/_testcapimodule.c259
-rw-r--r--PCbuild/_testcapi.vcxproj1
-rw-r--r--PCbuild/_testcapi.vcxproj.filters3
-rw-r--r--setup.py2
9 files changed, 292 insertions, 253 deletions
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 84c7833..c17c3d6 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -2568,7 +2568,7 @@ MODULE__SHA3_DEPS=$(srcdir)/Modules/_sha3/sha3.c $(srcdir)/Modules/_sha3/sha3.h
MODULE__SHA512_DEPS=$(srcdir)/Modules/hashlib.h
MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h
MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data.h $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h
-MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/testcapi_long.h
+MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/testcapi_long.h Modules/_testcapi/parts.h $(srcdir)/Modules/_testcapi/vectorcall.c
MODULE__SQLITE3_DEPS=$(srcdir)/Modules/_sqlite/connection.h $(srcdir)/Modules/_sqlite/cursor.h $(srcdir)/Modules/_sqlite/microprotocols.h $(srcdir)/Modules/_sqlite/module.h $(srcdir)/Modules/_sqlite/prepare_protocol.h $(srcdir)/Modules/_sqlite/row.h $(srcdir)/Modules/_sqlite/util.h
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in
index 7357aac..581a5c7 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -168,7 +168,7 @@
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c
-@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c
+@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c
# Some testing modules MUST be built as shared libraries.
*shared*
diff --git a/Modules/_testcapi/README.txt b/Modules/_testcapi/README.txt
new file mode 100644
index 0000000..134b6ef
--- /dev/null
+++ b/Modules/_testcapi/README.txt
@@ -0,0 +1,3 @@
+Tests in this directory are compiled into the _testcapi extension.
+The main file for the extension is Modules/_testcapimodule.c, which
+calls `_PyTestCapi_Init_*` from these functions.
diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h
new file mode 100644
index 0000000..1111021
--- /dev/null
+++ b/Modules/_testcapi/parts.h
@@ -0,0 +1,3 @@
+#include "Python.h"
+
+PyAPI_FUNC(int) _PyTestCapi_Init_Vectorcall(PyObject *module);
diff --git a/Modules/_testcapi/vectorcall.c b/Modules/_testcapi/vectorcall.c
new file mode 100644
index 0000000..9bc7029
--- /dev/null
+++ b/Modules/_testcapi/vectorcall.c
@@ -0,0 +1,270 @@
+#include "parts.h"
+#include <stddef.h> // offsetof
+
+
+/* Test PEP 590 - Vectorcall */
+
+static int
+fastcall_args(PyObject *args, PyObject ***stack, Py_ssize_t *nargs)
+{
+ if (args == Py_None) {
+ *stack = NULL;
+ *nargs = 0;
+ }
+ else if (PyTuple_Check(args)) {
+ *stack = ((PyTupleObject *)args)->ob_item;
+ *nargs = PyTuple_GET_SIZE(args);
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "args must be None or a tuple");
+ return -1;
+ }
+ return 0;
+}
+
+
+static PyObject *
+test_pyobject_fastcall(PyObject *self, PyObject *args)
+{
+ PyObject *func, *func_args;
+ PyObject **stack;
+ Py_ssize_t nargs;
+
+ if (!PyArg_ParseTuple(args, "OO", &func, &func_args)) {
+ return NULL;
+ }
+
+ if (fastcall_args(func_args, &stack, &nargs) < 0) {
+ return NULL;
+ }
+ return _PyObject_FastCall(func, stack, nargs);
+}
+
+static PyObject *
+test_pyobject_fastcalldict(PyObject *self, PyObject *args)
+{
+ PyObject *func, *func_args, *kwargs;
+ PyObject **stack;
+ Py_ssize_t nargs;
+
+ if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwargs)) {
+ return NULL;
+ }
+
+ if (fastcall_args(func_args, &stack, &nargs) < 0) {
+ return NULL;
+ }
+
+ if (kwargs == Py_None) {
+ kwargs = NULL;
+ }
+ else if (!PyDict_Check(kwargs)) {
+ PyErr_SetString(PyExc_TypeError, "kwnames must be None or a dict");
+ return NULL;
+ }
+
+ return PyObject_VectorcallDict(func, stack, nargs, kwargs);
+}
+
+static PyObject *
+test_pyobject_vectorcall(PyObject *self, PyObject *args)
+{
+ PyObject *func, *func_args, *kwnames = NULL;
+ PyObject **stack;
+ Py_ssize_t nargs, nkw;
+
+ if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwnames)) {
+ return NULL;
+ }
+
+ if (fastcall_args(func_args, &stack, &nargs) < 0) {
+ return NULL;
+ }
+
+ if (kwnames == Py_None) {
+ kwnames = NULL;
+ }
+ else if (PyTuple_Check(kwnames)) {
+ nkw = PyTuple_GET_SIZE(kwnames);
+ if (nargs < nkw) {
+ PyErr_SetString(PyExc_ValueError, "kwnames longer than args");
+ return NULL;
+ }
+ nargs -= nkw;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple");
+ return NULL;
+ }
+ return PyObject_Vectorcall(func, stack, nargs, kwnames);
+}
+
+static PyObject *
+test_pyvectorcall_call(PyObject *self, PyObject *args)
+{
+ PyObject *func;
+ PyObject *argstuple;
+ PyObject *kwargs = NULL;
+
+ if (!PyArg_ParseTuple(args, "OO|O", &func, &argstuple, &kwargs)) {
+ return NULL;
+ }
+
+ if (!PyTuple_Check(argstuple)) {
+ PyErr_SetString(PyExc_TypeError, "args must be a tuple");
+ return NULL;
+ }
+ if (kwargs != NULL && !PyDict_Check(kwargs)) {
+ PyErr_SetString(PyExc_TypeError, "kwargs must be a dict");
+ return NULL;
+ }
+
+ return PyVectorcall_Call(func, argstuple, kwargs);
+}
+
+static PyMethodDef TestMethods[] = {
+ {"pyobject_fastcall", test_pyobject_fastcall, METH_VARARGS},
+ {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS},
+ {"pyobject_vectorcall", test_pyobject_vectorcall, METH_VARARGS},
+ {"pyvectorcall_call", test_pyvectorcall_call, METH_VARARGS},
+ {NULL},
+};
+
+
+typedef struct {
+ PyObject_HEAD
+ vectorcallfunc vectorcall;
+} MethodDescriptorObject;
+
+static PyObject *
+MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args,
+ size_t nargsf, PyObject *kwnames)
+{
+ /* True if using the vectorcall function in MethodDescriptorObject
+ * but False for MethodDescriptor2Object */
+ MethodDescriptorObject *md = (MethodDescriptorObject *)callable;
+ return PyBool_FromLong(md->vectorcall != NULL);
+}
+
+static PyObject *
+MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw)
+{
+ MethodDescriptorObject *op = (MethodDescriptorObject *)type->tp_alloc(type, 0);
+ op->vectorcall = MethodDescriptor_vectorcall;
+ return (PyObject *)op;
+}
+
+static PyObject *
+func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+ if (obj == Py_None || obj == NULL) {
+ Py_INCREF(func);
+ return func;
+ }
+ return PyMethod_New(func, obj);
+}
+
+static PyObject *
+nop_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+ Py_INCREF(func);
+ return func;
+}
+
+static PyObject *
+call_return_args(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ Py_INCREF(args);
+ return args;
+}
+
+static PyTypeObject MethodDescriptorBase_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "MethodDescriptorBase",
+ sizeof(MethodDescriptorObject),
+ .tp_new = MethodDescriptor_new,
+ .tp_call = PyVectorcall_Call,
+ .tp_vectorcall_offset = offsetof(MethodDescriptorObject, vectorcall),
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_HAVE_VECTORCALL,
+ .tp_descr_get = func_descr_get,
+};
+
+static PyTypeObject MethodDescriptorDerived_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "MethodDescriptorDerived",
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+};
+
+static PyTypeObject MethodDescriptorNopGet_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "MethodDescriptorNopGet",
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_call = call_return_args,
+ .tp_descr_get = nop_descr_get,
+};
+
+typedef struct {
+ MethodDescriptorObject base;
+ vectorcallfunc vectorcall;
+} MethodDescriptor2Object;
+
+static PyObject *
+MethodDescriptor2_new(PyTypeObject* type, PyObject* args, PyObject *kw)
+{
+ MethodDescriptor2Object *op = PyObject_New(MethodDescriptor2Object, type);
+ op->base.vectorcall = NULL;
+ op->vectorcall = MethodDescriptor_vectorcall;
+ return (PyObject *)op;
+}
+
+static PyTypeObject MethodDescriptor2_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "MethodDescriptor2",
+ sizeof(MethodDescriptor2Object),
+ .tp_new = MethodDescriptor2_new,
+ .tp_call = PyVectorcall_Call,
+ .tp_vectorcall_offset = offsetof(MethodDescriptor2Object, vectorcall),
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL,
+};
+
+
+int
+_PyTestCapi_Init_Vectorcall(PyObject *m) {
+ if (PyModule_AddFunctions(m, TestMethods) < 0) {
+ return -1;
+ }
+
+ if (PyType_Ready(&MethodDescriptorBase_Type) < 0) {
+ return -1;
+ }
+ if (PyModule_AddType(m, &MethodDescriptorBase_Type) < 0) {
+ return -1;
+ }
+
+ MethodDescriptorDerived_Type.tp_base = &MethodDescriptorBase_Type;
+ if (PyType_Ready(&MethodDescriptorDerived_Type) < 0) {
+ return -1;
+ }
+ if (PyModule_AddType(m, &MethodDescriptorDerived_Type) < 0) {
+ return -1;
+ }
+
+ MethodDescriptorNopGet_Type.tp_base = &MethodDescriptorBase_Type;
+ if (PyType_Ready(&MethodDescriptorNopGet_Type) < 0) {
+ return -1;
+ }
+ if (PyModule_AddType(m, &MethodDescriptorNopGet_Type) < 0) {
+ return -1;
+ }
+
+ MethodDescriptor2_Type.tp_base = &MethodDescriptorBase_Type;
+ if (PyType_Ready(&MethodDescriptor2_Type) < 0) {
+ return -1;
+ }
+ if (PyModule_AddType(m, &MethodDescriptor2_Type) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 7d88f4f..436c701 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -43,6 +43,10 @@
# error "The public headers should not include <stdbool.h>, see bpo-46748"
#endif
+// Several parts of this module are broken out into files in _testcapi/.
+// Include definitions from there.
+#include "_testcapi/parts.h"
+
// Forward declarations
static struct PyModuleDef _testcapimodule;
static PyType_Spec HeapTypeNameType_Spec;
@@ -5299,128 +5303,6 @@ raise_SIGINT_then_send_None(PyObject *self, PyObject *args)
}
-static int
-fastcall_args(PyObject *args, PyObject ***stack, Py_ssize_t *nargs)
-{
- if (args == Py_None) {
- *stack = NULL;
- *nargs = 0;
- }
- else if (PyTuple_Check(args)) {
- *stack = ((PyTupleObject *)args)->ob_item;
- *nargs = PyTuple_GET_SIZE(args);
- }
- else {
- PyErr_SetString(PyExc_TypeError, "args must be None or a tuple");
- return -1;
- }
- return 0;
-}
-
-
-static PyObject *
-test_pyobject_fastcall(PyObject *self, PyObject *args)
-{
- PyObject *func, *func_args;
- PyObject **stack;
- Py_ssize_t nargs;
-
- if (!PyArg_ParseTuple(args, "OO", &func, &func_args)) {
- return NULL;
- }
-
- if (fastcall_args(func_args, &stack, &nargs) < 0) {
- return NULL;
- }
- return _PyObject_FastCall(func, stack, nargs);
-}
-
-
-static PyObject *
-test_pyobject_fastcalldict(PyObject *self, PyObject *args)
-{
- PyObject *func, *func_args, *kwargs;
- PyObject **stack;
- Py_ssize_t nargs;
-
- if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwargs)) {
- return NULL;
- }
-
- if (fastcall_args(func_args, &stack, &nargs) < 0) {
- return NULL;
- }
-
- if (kwargs == Py_None) {
- kwargs = NULL;
- }
- else if (!PyDict_Check(kwargs)) {
- PyErr_SetString(PyExc_TypeError, "kwnames must be None or a dict");
- return NULL;
- }
-
- return PyObject_VectorcallDict(func, stack, nargs, kwargs);
-}
-
-
-static PyObject *
-test_pyobject_vectorcall(PyObject *self, PyObject *args)
-{
- PyObject *func, *func_args, *kwnames = NULL;
- PyObject **stack;
- Py_ssize_t nargs, nkw;
-
- if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwnames)) {
- return NULL;
- }
-
- if (fastcall_args(func_args, &stack, &nargs) < 0) {
- return NULL;
- }
-
- if (kwnames == Py_None) {
- kwnames = NULL;
- }
- else if (PyTuple_Check(kwnames)) {
- nkw = PyTuple_GET_SIZE(kwnames);
- if (nargs < nkw) {
- PyErr_SetString(PyExc_ValueError, "kwnames longer than args");
- return NULL;
- }
- nargs -= nkw;
- }
- else {
- PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple");
- return NULL;
- }
- return PyObject_Vectorcall(func, stack, nargs, kwnames);
-}
-
-
-static PyObject *
-test_pyvectorcall_call(PyObject *self, PyObject *args)
-{
- PyObject *func;
- PyObject *argstuple;
- PyObject *kwargs = NULL;
-
- if (!PyArg_ParseTuple(args, "OO|O", &func, &argstuple, &kwargs)) {
- return NULL;
- }
-
- if (!PyTuple_Check(argstuple)) {
- PyErr_SetString(PyExc_TypeError, "args must be a tuple");
- return NULL;
- }
- if (kwargs != NULL && !PyDict_Check(kwargs)) {
- PyErr_SetString(PyExc_TypeError, "kwargs must be a dict");
- return NULL;
- }
-
- return PyVectorcall_Call(func, argstuple, kwargs);
-}
-
-
static PyObject*
stack_pointer(PyObject *self, PyObject *args)
{
@@ -6403,10 +6285,6 @@ static PyMethodDef TestMethods[] = {
{"tracemalloc_get_traceback", tracemalloc_get_traceback, METH_VARARGS},
{"dict_get_version", dict_get_version, METH_VARARGS},
{"raise_SIGINT_then_send_None", raise_SIGINT_then_send_None, METH_VARARGS},
- {"pyobject_fastcall", test_pyobject_fastcall, METH_VARARGS},
- {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS},
- {"pyobject_vectorcall", test_pyobject_vectorcall, METH_VARARGS},
- {"pyvectorcall_call", test_pyvectorcall_call, METH_VARARGS},
{"stack_pointer", stack_pointer, METH_NOARGS},
#ifdef W_STOPCODE
{"W_STOPCODE", py_w_stopcode, METH_VARARGS},
@@ -7009,106 +6887,6 @@ static PyTypeObject Generic_Type = {
.tp_methods = generic_methods,
};
-
-/* Test PEP 590 */
-
-typedef struct {
- PyObject_HEAD
- vectorcallfunc vectorcall;
-} MethodDescriptorObject;
-
-static PyObject *
-MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args,
- size_t nargsf, PyObject *kwnames)
-{
- /* True if using the vectorcall function in MethodDescriptorObject
- * but False for MethodDescriptor2Object */
- MethodDescriptorObject *md = (MethodDescriptorObject *)callable;
- return PyBool_FromLong(md->vectorcall != NULL);
-}
-
-static PyObject *
-MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw)
-{
- MethodDescriptorObject *op = (MethodDescriptorObject *)type->tp_alloc(type, 0);
- op->vectorcall = MethodDescriptor_vectorcall;
- return (PyObject *)op;
-}
-
-static PyObject *
-func_descr_get(PyObject *func, PyObject *obj, PyObject *type)
-{
- if (obj == Py_None || obj == NULL) {
- Py_INCREF(func);
- return func;
- }
- return PyMethod_New(func, obj);
-}
-
-static PyObject *
-nop_descr_get(PyObject *func, PyObject *obj, PyObject *type)
-{
- Py_INCREF(func);
- return func;
-}
-
-static PyObject *
-call_return_args(PyObject *self, PyObject *args, PyObject *kwargs)
-{
- Py_INCREF(args);
- return args;
-}
-
-static PyTypeObject MethodDescriptorBase_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "MethodDescriptorBase",
- sizeof(MethodDescriptorObject),
- .tp_new = MethodDescriptor_new,
- .tp_call = PyVectorcall_Call,
- .tp_vectorcall_offset = offsetof(MethodDescriptorObject, vectorcall),
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
- Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_HAVE_VECTORCALL,
- .tp_descr_get = func_descr_get,
-};
-
-static PyTypeObject MethodDescriptorDerived_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "MethodDescriptorDerived",
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
-};
-
-static PyTypeObject MethodDescriptorNopGet_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "MethodDescriptorNopGet",
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_call = call_return_args,
- .tp_descr_get = nop_descr_get,
-};
-
-typedef struct {
- MethodDescriptorObject base;
- vectorcallfunc vectorcall;
-} MethodDescriptor2Object;
-
-static PyObject *
-MethodDescriptor2_new(PyTypeObject* type, PyObject* args, PyObject *kw)
-{
- MethodDescriptor2Object *op = PyObject_New(MethodDescriptor2Object, type);
- op->base.vectorcall = NULL;
- op->vectorcall = MethodDescriptor_vectorcall;
- return (PyObject *)op;
-}
-
-static PyTypeObject MethodDescriptor2_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "MethodDescriptor2",
- sizeof(MethodDescriptor2Object),
- .tp_new = MethodDescriptor2_new,
- .tp_call = PyVectorcall_Call,
- .tp_vectorcall_offset = offsetof(MethodDescriptor2Object, vectorcall),
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL,
-};
-
PyDoc_STRVAR(heapdocctype__doc__,
"HeapDocCType(arg1, arg2)\n"
"--\n"
@@ -7778,29 +7556,6 @@ PyInit__testcapi(void)
Py_INCREF(&MyList_Type);
PyModule_AddObject(m, "MyList", (PyObject *)&MyList_Type);
- if (PyType_Ready(&MethodDescriptorBase_Type) < 0)
- return NULL;
- Py_INCREF(&MethodDescriptorBase_Type);
- PyModule_AddObject(m, "MethodDescriptorBase", (PyObject *)&MethodDescriptorBase_Type);
-
- MethodDescriptorDerived_Type.tp_base = &MethodDescriptorBase_Type;
- if (PyType_Ready(&MethodDescriptorDerived_Type) < 0)
- return NULL;
- Py_INCREF(&MethodDescriptorDerived_Type);
- PyModule_AddObject(m, "MethodDescriptorDerived", (PyObject *)&MethodDescriptorDerived_Type);
-
- MethodDescriptorNopGet_Type.tp_base = &MethodDescriptorBase_Type;
- if (PyType_Ready(&MethodDescriptorNopGet_Type) < 0)
- return NULL;
- Py_INCREF(&MethodDescriptorNopGet_Type);
- PyModule_AddObject(m, "MethodDescriptorNopGet", (PyObject *)&MethodDescriptorNopGet_Type);
-
- MethodDescriptor2_Type.tp_base = &MethodDescriptorBase_Type;
- if (PyType_Ready(&MethodDescriptor2_Type) < 0)
- return NULL;
- Py_INCREF(&MethodDescriptor2_Type);
- PyModule_AddObject(m, "MethodDescriptor2", (PyObject *)&MethodDescriptor2_Type);
-
if (PyType_Ready(&GenericAlias_Type) < 0)
return NULL;
Py_INCREF(&GenericAlias_Type);
@@ -7973,6 +7728,11 @@ PyInit__testcapi(void)
(PyObject *) &ContainerNoGC_type) < 0)
return NULL;
+ /* Include tests from the _testcapi/ directory */
+ if (_PyTestCapi_Init_Vectorcall(m) < 0) {
+ return NULL;
+ }
+
PyState_AddModule(m, &_testcapimodule);
return m;
}
@@ -8024,7 +7784,6 @@ test_buildvalue_issue38913(PyObject *self, PyObject *Py_UNUSED(ignored))
}
PyErr_Clear();
-
Py_RETURN_NONE;
}
diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj
index c1a1943..07e2355 100644
--- a/PCbuild/_testcapi.vcxproj
+++ b/PCbuild/_testcapi.vcxproj
@@ -94,6 +94,7 @@
</PropertyGroup>
<ItemGroup>
<ClCompile Include="..\Modules\_testcapimodule.c" />
+ <ClCompile Include="..\Modules\_testcapi\vectorcall.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc" />
diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters
index 53f64b7..82fce05 100644
--- a/PCbuild/_testcapi.vcxproj.filters
+++ b/PCbuild/_testcapi.vcxproj.filters
@@ -12,6 +12,9 @@
<ClCompile Include="..\Modules\_testcapimodule.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\Modules\_testcapi\vectorcall.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc">
diff --git a/setup.py b/setup.py
index 2edcb08..7c71ac6 100644
--- a/setup.py
+++ b/setup.py
@@ -994,7 +994,7 @@ class PyBuildExt(build_ext):
def detect_test_extensions(self):
# Python C API test module
- self.addext(Extension('_testcapi', ['_testcapimodule.c']))
+ self.addext(Extension('_testcapi', ['_testcapimodule.c', '_testcapi/vectorcall.c']))
# Python Internal C API test module
self.addext(Extension('_testinternalcapi', ['_testinternalcapi.c']))