You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
memoryview & ctypes: incorrect itemsize for empty array #76963
This issue is about the itemsize attribute of instances of the built-in memoryview class. Ctypes in only involved in providing format information. Hence the nosy additions.
On Win10 with 3.8, ctypes has no uint attributes. Using 'c_int32' instead, I see the same behavior (itemsize 0 for empty structure).
"This is a storage for the itemsize (in bytes) of each element of the shared memory. It is technically un-necessary as it can be obtained using PyBuffer_SizeFromFormat, however an exporter may know this information without parsing the format string and it is necessary to know the itemsize for proper interpretation of striding. Therefore, storing it is more convenient and faster."
The first line could be seen as implying that itemsize is undefined if there are no items (and as justifying numbytes/numitems otherwise). The 0 return could be seen as equivalent to a None return from a python-coded function. If so, it is not a bug, and there might be code that would break if it is changed.
On the other hand, the next lines imply that itemsize is *usually*, though not necessarily, a cache for PyBuffer_SizeFromFormat. This could be seen as implying that in the absence of other information, the itemsize should be calculated from the format, making 0 a bug.
changed the title [-]ctypes: memoryview gives incorrect PEP3118 itemsize for array of length zero[/-][+]memoryview gives incorrect PEP3118 itemsize for empty array[/+]on Apr 14, 2019
https://docs.python.org/3/library/stdtypes.html#typememoryview
says "itemsize The size in bytes of each element of the memoryview"
Revising the code example to use an empty array:
>>> import array, struct
>>> m =memoryview(array.array('H', [0])
>>> m.itemsize
2
I agree that itemsize should also be non-zero for ctype formats.
Activity
eric-wieser commentedon Feb 6, 2018
Take the following simple structure:
And construct some arrays with it:
In most cases, this works as expected, returning the size of one item:
>>> get_array_view(10).itemsize 4 >>> get_array_view(1).itemsize 4But when N=0, it returns the wrong result
>>> get_array_view(0).itemsize 0Which contradicts its
.format, which still describes a 4-byte struct>>> get_array_view(0).format 'T{>I:one:}'This causes a downstream problem in numpy:
>>> np.array(get_array_view(0)) RuntimeWarning: Item size computed from the PEP 3118 buffer format string does not match the actual item size.eric-wieser commentedon Jul 8, 2018
Pinging, as recommended by https://devguide.python.org/pullrequest/#reviewing. Ideally this and https://bugs.python.org/issue32780 would make the same patch release.
eric-wieser commentedon Sep 6, 2018
Pinging again, for lack of a clearer path forward
terryjreedy commentedon Apr 14, 2019
This issue is about the itemsize attribute of instances of the built-in memoryview class. Ctypes in only involved in providing format information. Hence the nosy additions.
On Win10 with 3.8, ctypes has no uint attributes. Using 'c_int32' instead, I see the same behavior (itemsize 0 for empty structure).
About itemsize, https://www.python.org/dev/peps/pep-3118/ says
"This is a storage for the itemsize (in bytes) of each element of the shared memory. It is technically un-necessary as it can be obtained using PyBuffer_SizeFromFormat, however an exporter may know this information without parsing the format string and it is necessary to know the itemsize for proper interpretation of striding. Therefore, storing it is more convenient and faster."
The first line could be seen as implying that itemsize is undefined if there are no items (and as justifying numbytes/numitems otherwise). The 0 return could be seen as equivalent to a None return from a python-coded function. If so, it is not a bug, and there might be code that would break if it is changed.
On the other hand, the next lines imply that itemsize is *usually*, though not necessarily, a cache for PyBuffer_SizeFromFormat. This could be seen as implying that in the absence of other information, the itemsize should be calculated from the format, making 0 a bug.
[-]ctypes: memoryview gives incorrect PEP3118 itemsize for array of length zero[/-][+]memoryview gives incorrect PEP3118 itemsize for empty array[/+]terryjreedy commentedon Apr 14, 2019
This is actually about memoryview.itemsize within ctypes.
[-]memoryview gives incorrect PEP3118 itemsize for empty array[/-][+]memoryview & ctypes: incorrect PEP3118 itemsize for empty array[/+]terryjreedy commentedon Apr 14, 2019
[-]memoryview & ctypes: incorrect PEP3118 itemsize for empty array[/-][+]memoryview & ctypes: incorrect itemsize for empty array[/+]4 remaining items
gh-76963: PEP3118 itemsize of an empty ctypes array should not be 0 (G…
pythongh-76963: PEP3118 itemsize of an empty ctypes array should not …
pythongh-76963: PEP3118 itemsize of an empty ctypes array should not …
[3.10] gh-76963: PEP3118 itemsize of an empty ctypes array should not…
[3.11] gh-76963: PEP3118 itemsize of an empty ctypes array should not…
mattip commentedon Dec 23, 2022
Thanks for the fix that closed this. @eric-wieser do you remember where this impacted NumPy? I don't see the relevant issue or PR.
eric-wieser commentedon Dec 23, 2022
I think the workaround in numpy needs to stay till after #5561
eric-wieser commentedon Dec 23, 2022
The reference in numpy is here:
https://github.com/numpy/numpy/blob/85b26f4afc6e98694eab7a6d6abefbd3fed31fde/numpy/core/_dtype_ctypes.py#L21
Merged main into regmachine branch (#50)