From 95c55a69b3935e36108059ea89efd372d0902c6e Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 23 Dec 2022 00:55:55 -0800 Subject: [PATCH] [3.10] gh-76963: PEP3118 itemsize of an empty ctypes array should not be 0 (GH-5576) (#100451) gh-76963: PEP3118 itemsize of an empty ctypes array should not be 0 (GH-5576) The itemsize returned in a memoryview of a ctypes array is now computed from the item type, instead of dividing the total size by the length and assuming that the length is not zero. (cherry picked from commit 84bc6a4f25fcf467813ee12b74118f7b1b54e285) Co-authored-by: Eric Wieser --- Lib/ctypes/test/test_pep3118.py | 2 ++ .../2018-02-06-23-21-13.bpo-32782.EJVSfR.rst | 3 ++ Modules/_ctypes/_ctypes.c | 33 ++++++++++++++----- 3 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-02-06-23-21-13.bpo-32782.EJVSfR.rst diff --git a/Lib/ctypes/test/test_pep3118.py b/Lib/ctypes/test/test_pep3118.py index 81e8ca7638fdeb..efffc80a66fcb8 100644 --- a/Lib/ctypes/test/test_pep3118.py +++ b/Lib/ctypes/test/test_pep3118.py @@ -176,7 +176,9 @@ class Complete(Structure): ## arrays and pointers (c_double * 4, "proto; + assert(elem_type); + return PyCData_item_type(elem_type); + } + else { + return type; + } +} + +static int +PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags) { CDataObject *self = (CDataObject *)myself; StgDictObject *dict = PyObject_stgdict(myself); - Py_ssize_t i; + PyObject *item_type = PyCData_item_type((PyObject*)Py_TYPE(myself)); + StgDictObject *item_dict = PyType_stgdict(item_type); if (view == NULL) return 0; @@ -2812,12 +2834,7 @@ static int PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags) view->format = dict->format ? dict->format : "B"; view->ndim = dict->ndim; view->shape = dict->shape; - view->itemsize = self->b_size; - if (view->itemsize) { - for (i = 0; i < view->ndim; ++i) { - view->itemsize /= dict->shape[i]; - } - } + view->itemsize = item_dict->size; view->strides = NULL; view->suboffsets = NULL; view->internal = NULL;