Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit29b3c32

Browse files
committed
bpo-32782: PEP3118 itemsize of an empty ctypes array should not be 0
The itemsize returned in a memoryview of a ctypes array should be computed from the item type, not by dividing the total size by the length and assuming that the length is not zero.
1 parentc1e46e9 commit29b3c32

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

‎Lib/ctypes/test/test_pep3118.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,9 @@ class Complete(Structure):
176176
## arrays and pointers
177177

178178
(c_double*4,"<d", (4,),c_double),
179+
(c_double*0,"<d", (0,),c_double),
179180
(c_float*4*3*2,"<f", (2,3,4),c_float),
181+
(c_float*4*0*2,"<f", (2,0,4),c_float),
180182
(POINTER(c_short)*2,"&<"+s_short, (2,),POINTER(c_short)),
181183
(POINTER(c_short)*2*3,"&<"+s_short, (3,2,),POINTER(c_short)),
182184
(POINTER(c_short*2),"&(2)<"+s_short, (),POINTER(c_short)),
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
``ctypes`` arrays of length 0 now report a correct itemsize when a
2+
``memoryview`` is constructed from them, rather than always giving a value
3+
of 0.

‎Modules/_ctypes/_ctypes.c

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2596,10 +2596,45 @@ static PyMemberDef PyCData_members[] = {
25962596
{NULL },
25972597
};
25982598

2599+
/*
2600+
Get the StgDictObject corresponding to a single item of a multidimensional
2601+
array.
2602+
Takes and returns a borrowed reference.
2603+
*/
2604+
staticStgDictObject*PyCData_item_stgdict(StgDictObject*dict)
2605+
{
2606+
if (dict->ndim==0) {
2607+
/* scalar is its own item */
2608+
returndict;
2609+
}
2610+
else {
2611+
/* follow _type_, eliminating a dimension */
2612+
PyObject*type_attr;
2613+
StgDictObject*item_dict;
2614+
2615+
type_attr=PyDict_GetItemString((PyObject*)dict,"_type_");
2616+
if (!type_attr) {
2617+
PyErr_SetString(PyExc_AttributeError,
2618+
"class must define a '_type_' attribute");
2619+
returnNULL;
2620+
}
2621+
2622+
item_dict=PyType_stgdict(type_attr);
2623+
if (!item_dict) {
2624+
PyErr_SetString(PyExc_TypeError,
2625+
"_type_ must have storage info");
2626+
returnNULL;
2627+
}
2628+
2629+
returnPyCData_item_stgdict(item_dict);
2630+
}
2631+
}
2632+
25992633
staticintPyCData_NewGetBuffer(PyObject*myself,Py_buffer*view,intflags)
26002634
{
26012635
CDataObject*self= (CDataObject*)myself;
26022636
StgDictObject*dict=PyObject_stgdict(myself);
2637+
StgDictObject*item_dict;
26032638
Py_ssize_ti;
26042639

26052640
if (view==NULL)return0;
@@ -2613,12 +2648,11 @@ static int PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
26132648
view->format=dict->format ?dict->format :"B";
26142649
view->ndim=dict->ndim;
26152650
view->shape=dict->shape;
2616-
view->itemsize=self->b_size;
2617-
if (view->itemsize) {
2618-
for (i=0;i<view->ndim;++i) {
2619-
view->itemsize /=dict->shape[i];
2620-
}
2651+
item_dict=PyCData_item_stgdict(dict);
2652+
if (item_dict==NULL) {
2653+
return-1;
26212654
}
2655+
view->itemsize=item_dict->size;
26222656
view->strides=NULL;
26232657
view->suboffsets=NULL;
26242658
view->internal=NULL;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp