-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Closed
python/cpython
#5561Description
This seems like a bug inherited from ctypes, so maybe we need a workaround:
Start off with a very simple struct:
class foo(ctypes.Structure):
_fields_ = [('a', ctypes.c_uint8), ('b', ctypes.c_uint32)]
f = foo()
We'd expect this to insert padding, and it does:
>>> memoryview(f).itemsize # ok
8
But that padding doesn't show up in the format string:
>>> memoryview(f).format
'T{<B:a:<I:b:}'
The docs for struct
say that
No padding is added when using non-native size and alignment, e.g. with ‘<’, ‘>’ "
So this format has size 5, which contradicts itemsize
.
Sure enough, we catch this in our PEP3118 parser:
>>> np.array(f)
RuntimeWarning: Item size computed from the PEP 3118 buffer format string does not match the actual item size.
Out[45]: array(<__main__.foo object at 0x7f2715469bf8>, dtype=object)
I suspect there's already an issue for this - perhaps we need a PEP3118 tag.
The fix would be to special case ctypes
objects in the array constructor, and not call memoryview
on them because it doesn't actually work.
Worse yet, numpy doesn't stand a chance with an unpadded struct:
class foo(ctypes.Structure):
_fields_ = [('a', ctypes.c_uint8), ('b', ctypes.c_uint32)]
_pack_ = 1
f = foo()
>>> memoryview(f).itemsize # ok
5
>>> memoryview(f).format # WAT
'B'