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