Two issues with sip.array
Phil Thompson
phil at riverbankcomputing.com
Fri Feb 24 15:19:19 GMT 2023
The fixes will be in the next snapshot.
Thanks,
Phil
On 07/02/2023 16:04, Ognyan Moore wrote:
> Hi Phil,
>
> We have identified two issues with sip.array and I think we identified
> their respective fixes too.
>
> The first has to do with the buffer protocol, we have a work-around but
> here is some code to demonstrate the issue:
>
> from PyQt6 import QtCore, sip
> import numpy as np
>
>
> LEN = 5
> sa = sip.array(QtCore.QLineF, LEN) # LEN * 4 doubles
> assert len(sa) == LEN
>
>
> # following fails due to wrong size
> # memory = np.frombuffer(sa, dtype=np.float64)
> # ValueError: buffer size must be a multiple of element size
>
>
> vp = sip.voidptr(sa)
> print(f'expecting {LEN*4*8}, got {vp.getsize()}')
>
>
> # the following is our workaround
> vp.setsize(len(sa)*4*8)
> memory = np.frombuffer(vp, dtype=np.float64)
> assert len(memory) == LEN * 4
>
> The bug is in sip_array.c
> # static int sipArray_getbuffer(PyObject self, Py_bufferview, int
> flags)
> # view->len = array->len;
> # should be
> # view->len = array->len * array->stride;
> # https://docs.python.org/3/c-api/buffer.html#c.PyObject_GetBuffer
>
> The second issue is that slicing sip.array does not work:
>
> from PyQt6 import QtCore, sip
>
>
> sa1 = sip.array(QtCore.QLineF, 10)
> assert len(sa1) == 10
> sa2 = sa1[2:8]
> assert len(sa2) == 6
>
>
> vp1 = sip.voidptr(sa1)
> assert int(vp1) != 0
> vp2 = sip.voidptr(sa2)
> print(hex(int(vp2))) # NULL pointer
>
> The behavior we would expect is that slicing would yield a non-owning
> memory view.
>
> The bug is also in sip_array.c
> # static PyObject sipArray_subscript(PyObjectself, PyObject *key)
> # element(array->data, start)
> # should be
> # element(array, start)
>
> Thanks Phil!
> Ogi
More information about the PyQt
mailing list