Issue #14181: Test creating memoryviews from a static exporter with both
view.obj==NULL and view.obj==base.
This commit is contained in:
parent
8d217c6a71
commit
bf6c7eca43
|
@ -3515,6 +3515,100 @@ class TestBufferProtocol(unittest.TestCase):
|
|||
del y, z
|
||||
self.assertEqual(m[1:3], x[1:3])
|
||||
|
||||
def test_memoryview_from_static_exporter(self):
|
||||
|
||||
fmt = 'B'
|
||||
lst = [0,1,2,3,4,5,6,7,8,9,10,11]
|
||||
|
||||
# exceptions
|
||||
self.assertRaises(TypeError, staticarray, 1, 2, 3)
|
||||
|
||||
# view.obj==x
|
||||
x = staticarray()
|
||||
y = memoryview(x)
|
||||
self.verify(y, obj=x,
|
||||
itemsize=1, fmt=fmt, readonly=1,
|
||||
ndim=1, shape=[12], strides=[1],
|
||||
lst=lst)
|
||||
for i in range(12):
|
||||
self.assertEqual(y[i], i)
|
||||
del x
|
||||
del y
|
||||
|
||||
x = staticarray()
|
||||
y = memoryview(x)
|
||||
del y
|
||||
del x
|
||||
|
||||
x = staticarray()
|
||||
y = ndarray(x, getbuf=PyBUF_FULL_RO)
|
||||
z = ndarray(y, getbuf=PyBUF_FULL_RO)
|
||||
m = memoryview(z)
|
||||
self.assertIs(y.obj, x)
|
||||
self.assertIs(m.obj, z)
|
||||
self.verify(m, obj=z,
|
||||
itemsize=1, fmt=fmt, readonly=1,
|
||||
ndim=1, shape=[12], strides=[1],
|
||||
lst=lst)
|
||||
del x, y, z, m
|
||||
|
||||
x = staticarray()
|
||||
y = ndarray(x, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
|
||||
z = ndarray(y, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
|
||||
m = memoryview(z)
|
||||
self.assertIs(y.obj, x)
|
||||
self.assertIs(z.obj, x)
|
||||
self.assertIs(m.obj, x)
|
||||
self.verify(m, obj=x,
|
||||
itemsize=1, fmt=fmt, readonly=1,
|
||||
ndim=1, shape=[12], strides=[1],
|
||||
lst=lst)
|
||||
del x, y, z, m
|
||||
|
||||
# view.obj==NULL
|
||||
x = staticarray(legacy_mode=True)
|
||||
y = memoryview(x)
|
||||
self.verify(y, obj=None,
|
||||
itemsize=1, fmt=fmt, readonly=1,
|
||||
ndim=1, shape=[12], strides=[1],
|
||||
lst=lst)
|
||||
for i in range(12):
|
||||
self.assertEqual(y[i], i)
|
||||
del x
|
||||
del y
|
||||
|
||||
x = staticarray(legacy_mode=True)
|
||||
y = memoryview(x)
|
||||
del y
|
||||
del x
|
||||
|
||||
x = staticarray(legacy_mode=True)
|
||||
y = ndarray(x, getbuf=PyBUF_FULL_RO)
|
||||
z = ndarray(y, getbuf=PyBUF_FULL_RO)
|
||||
m = memoryview(z)
|
||||
self.assertIs(y.obj, None)
|
||||
self.assertIs(m.obj, z)
|
||||
self.verify(m, obj=z,
|
||||
itemsize=1, fmt=fmt, readonly=1,
|
||||
ndim=1, shape=[12], strides=[1],
|
||||
lst=lst)
|
||||
del x, y, z, m
|
||||
|
||||
x = staticarray(legacy_mode=True)
|
||||
y = ndarray(x, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
|
||||
z = ndarray(y, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
|
||||
m = memoryview(z)
|
||||
# Clearly setting view.obj==NULL is inferior, since it
|
||||
# messes up the redirection chain:
|
||||
self.assertIs(y.obj, None)
|
||||
self.assertIs(z.obj, y)
|
||||
self.assertIs(m.obj, y)
|
||||
self.verify(m, obj=y,
|
||||
itemsize=1, fmt=fmt, readonly=1,
|
||||
ndim=1, shape=[12], strides=[1],
|
||||
lst=lst)
|
||||
del x, y, z, m
|
||||
|
||||
def test_issue_7385(self):
|
||||
x = ndarray([1,2,3], shape=[3], flags=ND_GETBUF_FAIL)
|
||||
self.assertRaises(BufferError, memoryview, x)
|
||||
|
|
|
@ -2602,6 +2602,126 @@ static PyTypeObject NDArray_Type = {
|
|||
ndarray_new, /* tp_new */
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/* StaticArray Object */
|
||||
/**************************************************************************/
|
||||
|
||||
static PyTypeObject StaticArray_Type;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
int legacy_mode; /* if true, use the view.obj==NULL hack */
|
||||
} StaticArrayObject;
|
||||
|
||||
static char static_mem[12] = {0,1,2,3,4,5,6,7,8,9,10,11};
|
||||
static Py_ssize_t static_shape[1] = {12};
|
||||
static Py_ssize_t static_strides[1] = {1};
|
||||
static Py_buffer static_buffer = {
|
||||
static_mem, /* buf */
|
||||
NULL, /* obj */
|
||||
12, /* len */
|
||||
1, /* itemsize */
|
||||
1, /* readonly */
|
||||
1, /* ndim */
|
||||
"B", /* format */
|
||||
static_shape, /* shape */
|
||||
static_strides, /* strides */
|
||||
NULL, /* suboffsets */
|
||||
NULL /* internal */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
staticarray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
return (PyObject *)PyObject_New(StaticArrayObject, &StaticArray_Type);
|
||||
}
|
||||
|
||||
static int
|
||||
staticarray_init(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
StaticArrayObject *a = (StaticArrayObject *)self;
|
||||
static char *kwlist[] = {
|
||||
"legacy_mode", NULL
|
||||
};
|
||||
PyObject *legacy_mode = Py_False;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &legacy_mode))
|
||||
return -1;
|
||||
|
||||
a->legacy_mode = (legacy_mode != Py_False);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
staticarray_dealloc(StaticArrayObject *self)
|
||||
{
|
||||
PyObject_Del(self);
|
||||
}
|
||||
|
||||
/* Return a buffer for a PyBUF_FULL_RO request. Flags are not checked,
|
||||
which makes this object a non-compliant exporter! */
|
||||
static int
|
||||
staticarray_getbuf(StaticArrayObject *self, Py_buffer *view, int flags)
|
||||
{
|
||||
*view = static_buffer;
|
||||
|
||||
if (self->legacy_mode) {
|
||||
view->obj = NULL; /* Don't use this in new code. */
|
||||
}
|
||||
else {
|
||||
view->obj = (PyObject *)self;
|
||||
Py_INCREF(view->obj);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyBufferProcs staticarray_as_buffer = {
|
||||
(getbufferproc)staticarray_getbuf, /* bf_getbuffer */
|
||||
NULL, /* bf_releasebuffer */
|
||||
};
|
||||
|
||||
static PyTypeObject StaticArray_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"staticarray", /* Name of this type */
|
||||
sizeof(StaticArrayObject), /* Basic object size */
|
||||
0, /* Item size for varobject */
|
||||
(destructor)staticarray_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_compare */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
0, /* tp_as_sequence */
|
||||
0, /* tp_as_mapping */
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
&staticarray_as_buffer, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
0, /* tp_iternext */
|
||||
0, /* tp_methods */
|
||||
0, /* tp_members */
|
||||
0, /* tp_getset */
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
0, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
staticarray_init, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
staticarray_new, /* tp_new */
|
||||
};
|
||||
|
||||
|
||||
static struct PyMethodDef _testbuffer_functions[] = {
|
||||
{"slice_indices", slice_indices, METH_VARARGS, NULL},
|
||||
|
@ -2634,10 +2754,14 @@ PyInit__testbuffer(void)
|
|||
if (m == NULL)
|
||||
return NULL;
|
||||
|
||||
Py_TYPE(&NDArray_Type)=&PyType_Type;
|
||||
Py_TYPE(&NDArray_Type) = &PyType_Type;
|
||||
Py_INCREF(&NDArray_Type);
|
||||
PyModule_AddObject(m, "ndarray", (PyObject *)&NDArray_Type);
|
||||
|
||||
Py_TYPE(&StaticArray_Type) = &PyType_Type;
|
||||
Py_INCREF(&StaticArray_Type);
|
||||
PyModule_AddObject(m, "staticarray", (PyObject *)&StaticArray_Type);
|
||||
|
||||
structmodule = PyImport_ImportModule("struct");
|
||||
if (structmodule == NULL)
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue