<div dir="ltr">Hi Phil,<div><br></div><div>We have identified two issues with sip.array and I think we identified their respective fixes too.</div><div><br></div><div>The first has to do with the buffer protocol, we have a work-around but here is some code to demonstrate the issue:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>from PyQt6 import QtCore, sip</div><div>import numpy as np</div></blockquote><div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div><br></div><div>LEN = 5</div><div>sa = sip.array(QtCore.QLineF, LEN)   # LEN * 4 doubles</div><div>assert len(sa) == LEN</div></blockquote></div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div># following fails due to wrong size</div><div># memory = np.frombuffer(sa, dtype=np.float64)</div><div># ValueError: buffer size must be a multiple of element size</div></blockquote><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>vp = sip.voidptr(sa)</div><div>print(f'expecting {LEN*4*8}, got {vp.getsize()}')</div></blockquote><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div># the following is our workaround </div><div>vp.setsize(len(sa)*4*8)</div><div>memory = np.frombuffer(vp, dtype=np.float64)</div><div>assert len(memory) == LEN * 4</div><div><br></div></blockquote><div>The bug is in sip_array.c<br># static int sipArray_getbuffer(PyObject self, Py_bufferview, int flags)<br>#    view->len = array->len;<br># should be<br>#    view->len = array->len * array->stride;<br># <a href="https://docs.python.org/3/c-api/buffer.html#c.PyObject_GetBuffer">https://docs.python.org/3/c-api/buffer.html#c.PyObject_GetBuffer</a><br></div><div><br></div><div>The second issue is that slicing sip.array does not work:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>from PyQt6 import QtCore, sip</div></blockquote><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>sa1 = sip.array(QtCore.QLineF, 10)</div><div>assert len(sa1) == 10</div><div>sa2 = sa1[2:8]</div><div>assert len(sa2) == 6</div></blockquote><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>vp1 = sip.voidptr(sa1)</div><div>assert int(vp1) != 0</div><div>vp2 = sip.voidptr(sa2)</div><div>print(hex(int(vp2)))    # NULL pointer</div><div><br></div></blockquote>The behavior we would expect is that slicing would yield a non-owning memory view.  <div><br></div><div>The bug is also in sip_array.c<div># static PyObject sipArray_subscript(PyObjectself, PyObject *key)<br>#   element(array->data, start)<br># should be<br>#   element(array, start)</div><div><br></div><div>Thanks Phil!</div><div>Ogi<br><div><br></div></div></div></div>