From 3f16b927b6791867124ec969049fde4d61df0157 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 9 Apr 2014 23:55:56 -0400 Subject: PEP 465: a dedicated infix operator for matrix multiplication (closes #21176) --- Modules/_testcapimodule.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'Modules/_testcapimodule.c') diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index db2376d036..291eee69ef 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3298,6 +3298,109 @@ static PyTypeObject test_structmembersType = { }; +typedef struct { + PyObject_HEAD +} matmulObject; + +static PyObject * +matmulType_matmul(PyObject *self, PyObject *other) +{ + return Py_BuildValue("(sOO)", "matmul", self, other); +} + +static PyObject * +matmulType_imatmul(PyObject *self, PyObject *other) +{ + return Py_BuildValue("(sOO)", "imatmul", self, other); +} + +static void +matmulType_dealloc(PyObject *self) +{ + return Py_TYPE(self)->tp_free(self); +} + +static PyNumberMethods matmulType_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainde r*/ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* tp_positive */ + 0, /* tp_absolute */ + 0, /* tp_bool */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + 0, /* nb_int */ + 0, /* nb_reserved */ + 0, /* nb_float */ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + 0, /* nb_index */ + matmulType_matmul, /* nb_matrix_multiply */ + matmulType_imatmul /* nb_matrix_inplace_multiply */ +}; + +static PyTypeObject matmulType = { + PyVarObject_HEAD_INIT(NULL, 0) + "matmulType", + sizeof(matmulObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + matmulType_dealloc, /* destructor tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + &matmulType_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + "C level type with matrix operations defined", + 0, /* traverseproc tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + PyType_GenericNew, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + static struct PyModuleDef _testcapimodule = { PyModuleDef_HEAD_INIT, @@ -3327,6 +3430,10 @@ PyInit__testcapi(void) /* don't use a name starting with "test", since we don't want test_capi to automatically call this */ PyModule_AddObject(m, "_test_structmembersType", (PyObject *)&test_structmembersType); + if (PyType_Ready(&matmulType) < 0) + return NULL; + Py_INCREF(&matmulType); + PyModule_AddObject(m, "matmulType", (PyObject *)&matmulType); PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX)); PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN)); -- cgit v1.2.1 From 95786a96fb11060c6fd20ee70611ec936d20dcc5 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Wed, 23 Apr 2014 13:51:27 -0500 Subject: Fix compiler warning on Windows ..\Modules\_testcapimodule.c(3320): warning C4098: 'matmulType_dealloc' : 'void' function returning a value --- Modules/_testcapimodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Modules/_testcapimodule.c') diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 291eee69ef..750e90fa4c 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3317,7 +3317,7 @@ matmulType_imatmul(PyObject *self, PyObject *other) static void matmulType_dealloc(PyObject *self) { - return Py_TYPE(self)->tp_free(self); + Py_TYPE(self)->tp_free(self); } static PyNumberMethods matmulType_as_number = { -- cgit v1.2.1 From 595eab7fac1c64b8a25352d0dd40f1e7b62ee58a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 2 May 2014 22:31:14 +0200 Subject: Issue #21233: Add new C functions: PyMem_RawCalloc(), PyMem_Calloc(), PyObject_Calloc(), _PyObject_GC_Calloc(). bytes(int) and bytearray(int) are now using ``calloc()`` instead of ``malloc()`` for large objects which is faster and use less memory (until the bytearray buffer is filled with data). --- Modules/_testcapimodule.c | 73 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 5 deletions(-) (limited to 'Modules/_testcapimodule.c') diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 750e90fa4c..a75500426c 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2710,6 +2710,20 @@ test_pymem_alloc0(PyObject *self) { void *ptr; + ptr = PyMem_RawMalloc(0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyMem_RawMalloc(0) returns NULL"); + return NULL; + } + PyMem_RawFree(ptr); + + ptr = PyMem_RawCalloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyMem_RawCalloc(0, 0) returns NULL"); + return NULL; + } + PyMem_RawFree(ptr); + ptr = PyMem_Malloc(0); if (ptr == NULL) { PyErr_SetString(PyExc_RuntimeError, "PyMem_Malloc(0) returns NULL"); @@ -2717,6 +2731,13 @@ test_pymem_alloc0(PyObject *self) } PyMem_Free(ptr); + ptr = PyMem_Calloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyMem_Calloc(0, 0) returns NULL"); + return NULL; + } + PyMem_Free(ptr); + ptr = PyObject_Malloc(0); if (ptr == NULL) { PyErr_SetString(PyExc_RuntimeError, "PyObject_Malloc(0) returns NULL"); @@ -2724,6 +2745,13 @@ test_pymem_alloc0(PyObject *self) } PyObject_Free(ptr); + ptr = PyObject_Calloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyObject_Calloc(0, 0) returns NULL"); + return NULL; + } + PyObject_Free(ptr); + Py_RETURN_NONE; } @@ -2731,6 +2759,8 @@ typedef struct { PyMemAllocator alloc; size_t malloc_size; + size_t calloc_nelem; + size_t calloc_elsize; void *realloc_ptr; size_t realloc_new_size; void *free_ptr; @@ -2743,6 +2773,14 @@ static void* hook_malloc (void* ctx, size_t size) return hook->alloc.malloc(hook->alloc.ctx, size); } +static void* hook_calloc (void* ctx, size_t nelem, size_t elsize) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->calloc_nelem = nelem; + hook->calloc_elsize = elsize; + return hook->alloc.calloc(hook->alloc.ctx, nelem, elsize); +} + static void* hook_realloc (void* ctx, void* ptr, size_t new_size) { alloc_hook_t *hook = (alloc_hook_t *)ctx; @@ -2765,16 +2803,14 @@ test_setallocators(PyMemAllocatorDomain domain) const char *error_msg; alloc_hook_t hook; PyMemAllocator alloc; - size_t size, size2; + size_t size, size2, nelem, elsize; void *ptr, *ptr2; - hook.malloc_size = 0; - hook.realloc_ptr = NULL; - hook.realloc_new_size = 0; - hook.free_ptr = NULL; + memset(&hook, 0, sizeof(hook)); alloc.ctx = &hook; alloc.malloc = &hook_malloc; + alloc.calloc = &hook_calloc; alloc.realloc = &hook_realloc; alloc.free = &hook_free; PyMem_GetAllocator(domain, &hook.alloc); @@ -2831,6 +2867,33 @@ test_setallocators(PyMemAllocatorDomain domain) goto fail; } + nelem = 2; + elsize = 5; + switch(domain) + { + case PYMEM_DOMAIN_RAW: ptr = PyMem_RawCalloc(nelem, elsize); break; + case PYMEM_DOMAIN_MEM: ptr = PyMem_Calloc(nelem, elsize); break; + case PYMEM_DOMAIN_OBJ: ptr = PyObject_Calloc(nelem, elsize); break; + default: ptr = NULL; break; + } + + if (ptr == NULL) { + error_msg = "calloc failed"; + goto fail; + } + + if (hook.calloc_nelem != nelem || hook.calloc_elsize != elsize) { + error_msg = "calloc invalid nelem or elsize"; + goto fail; + } + + switch(domain) + { + case PYMEM_DOMAIN_RAW: PyMem_RawFree(ptr); break; + case PYMEM_DOMAIN_MEM: PyMem_Free(ptr); break; + case PYMEM_DOMAIN_OBJ: PyObject_Free(ptr); break; + } + Py_INCREF(Py_None); res = Py_None; goto finally; -- cgit v1.2.1 From 1be655495f46dd956c0df2bb04f237e1d127e762 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 2 Jun 2014 21:57:10 +0200 Subject: Issue #21233: Rename the C structure "PyMemAllocator" to "PyMemAllocatorEx" to make sure that the code using it will be adapted for the new "calloc" field (instead of crashing). --- Modules/_testcapimodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Modules/_testcapimodule.c') diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index c83a4c8ce5..05a27d61f6 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2756,7 +2756,7 @@ test_pymem_alloc0(PyObject *self) } typedef struct { - PyMemAllocator alloc; + PyMemAllocatorEx alloc; size_t malloc_size; size_t calloc_nelem; @@ -2802,7 +2802,7 @@ test_setallocators(PyMemAllocatorDomain domain) PyObject *res = NULL; const char *error_msg; alloc_hook_t hook; - PyMemAllocator alloc; + PyMemAllocatorEx alloc; size_t size, size2, nelem, elsize; void *ptr, *ptr2; -- cgit v1.2.1 From c71951280e6bfcef072f7cd044046ca0ffa2ecfd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 21 Jul 2014 12:30:22 +0200 Subject: Issue #22018: Add _testcapi.raise_signal() - Use _testcapi.raise_signal() in test_signal - close also os.pipe() file descriptors in some test_signal tests where they were not closed properly - Remove faulthandler._sigill() and faulthandler._sigbus(): reuse _testcapi.raise_signal() in test_faulthandler --- Modules/_testcapimodule.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'Modules/_testcapimodule.c') diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 05a27d61f6..ebbf88f71a 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -11,6 +11,7 @@ #include #include "structmember.h" #include "datetime.h" +#include #ifdef WITH_THREAD #include "pythread.h" @@ -3063,6 +3064,24 @@ exit: } #endif /* WITH_THREAD */ +static PyObject* +test_raise_signal(PyObject* self, PyObject *args) +{ + int signum, err; + + if (PyArg_ParseTuple(args, "i:raise_signal", &signum) < 0) + return NULL; + + err = raise(signum); + if (err) + return PyErr_SetFromErrno(PyExc_OSError); + + if (PyErr_CheckSignals() < 0) + return NULL; + + Py_RETURN_NONE; +} + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, @@ -3198,6 +3217,8 @@ static PyMethodDef TestMethods[] = { {"docstring_with_signature_with_defaults", (PyCFunction)test_with_docstring, METH_NOARGS, docstring_with_signature_with_defaults}, + {"raise_signal", + (PyCFunction)test_raise_signal, METH_VARARGS}, #ifdef WITH_THREAD {"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_O, PyDoc_STR("set_error_class(error_class) -> None")}, -- cgit v1.2.1 From f6843defec386221310ff7cd64c1c457b9c1a6f4 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 6 Aug 2014 19:31:40 -0400 Subject: Issue #22116: C functions and methods (of the 'builtin_function_or_method' type) can now be weakref'ed. Patch by Wei Wu. --- Modules/_testcapimodule.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'Modules/_testcapimodule.c') diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index ebbf88f71a..9f20abb208 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2653,6 +2653,21 @@ with_tp_del(PyObject *self, PyObject *args) return obj; } +static PyMethodDef ml; + +static PyObject * +create_cfunction(PyObject *self, PyObject *args) +{ + return PyCFunction_NewEx(&ml, self, NULL); +} + +static PyMethodDef ml = { + "create_cfunction", + create_cfunction, + METH_NOARGS, + NULL +}; + static PyObject * _test_incref(PyObject *ob) { @@ -3186,6 +3201,7 @@ static PyMethodDef TestMethods[] = { {"pytime_object_to_timeval", test_pytime_object_to_timeval, METH_VARARGS}, {"pytime_object_to_timespec", test_pytime_object_to_timespec, METH_VARARGS}, {"with_tp_del", with_tp_del, METH_VARARGS}, + {"create_cfunction", create_cfunction, METH_NOARGS}, {"test_pymem_alloc0", (PyCFunction)test_pymem_alloc0, METH_NOARGS}, {"test_pymem_setrawallocators", -- cgit v1.2.1 From 5b0efc37029d1ed25416801b1f78e306aa01670e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 16 Aug 2014 01:03:39 +0200 Subject: Issue #22156: Fix some "comparison between signed and unsigned integers" compiler warnings in the Modules/ subdirectory. --- Modules/_testcapimodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Modules/_testcapimodule.c') diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 9f20abb208..643cbde317 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1719,7 +1719,7 @@ test_long_numbits(PyObject *self) {-0xffffL, 16, -1}, {0xfffffffL, 28, 1}, {-0xfffffffL, 28, -1}}; - int i; + size_t i; for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) { size_t nbits; -- cgit v1.2.1