summaryrefslogtreecommitdiff
path: root/Modules/_testbuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_testbuffer.c')
-rw-r--r--Modules/_testbuffer.c61
1 files changed, 40 insertions, 21 deletions
diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c
index 176df7c5ba..43db8a8e53 100644
--- a/Modules/_testbuffer.c
+++ b/Modules/_testbuffer.c
@@ -190,7 +190,7 @@ ndbuf_delete(NDArrayObject *nd, ndbuf_t *elt)
elt->prev->next = elt->next;
else
nd->head = elt->next;
-
+
if (elt->next)
elt->next->prev = elt->prev;
@@ -767,7 +767,7 @@ out:
+-----------------+-----------+-------------+----------------+
| base.readonly | 0 | OK | OK |
+-----------------+-----------+-------------+----------------+
- | base.format | NULL | OK | OK |
+ | base.format | NULL | OK | OK |
+-----------------+-----------+-------------+----------------+
| base.ndim | 1 | 1 | OK |
+-----------------+-----------+-------------+----------------+
@@ -1510,6 +1510,19 @@ ndarray_getbuf(NDArrayObject *self, Py_buffer *view, int flags)
view->shape = NULL;
}
+ /* Ascertain that the new buffer has the same contiguity as the exporter */
+ if (ND_C_CONTIGUOUS(baseflags) != PyBuffer_IsContiguous(view, 'C') ||
+ /* skip cast to 1-d */
+ (view->format != NULL && view->shape != NULL &&
+ ND_FORTRAN_CONTIGUOUS(baseflags) != PyBuffer_IsContiguous(view, 'F')) ||
+ /* cast to 1-d */
+ (view->format == NULL && view->shape == NULL &&
+ !PyBuffer_IsContiguous(view, 'F'))) {
+ PyErr_SetString(PyExc_BufferError,
+ "ndarray: contiguity mismatch in getbuf()");
+ return -1;
+ }
+
view->obj = (PyObject *)self;
Py_INCREF(view->obj);
self->head->exports++;
@@ -2005,7 +2018,7 @@ ndarray_get_obj(NDArrayObject *self, void *closure)
{
Py_buffer *base = &self->head->base;
- if (base->obj == NULL) {
+ if (base->obj == NULL) {
Py_RETURN_NONE;
}
Py_INCREF(base->obj);
@@ -2206,6 +2219,8 @@ ndarray_add_suboffsets(PyObject *self, PyObject *dummy)
for (i = 0; i < base->ndim; i++)
base->suboffsets[i] = -1;
+ nd->head->flags &= ~(ND_C|ND_FORTRAN);
+
Py_RETURN_NONE;
}
@@ -2469,13 +2484,12 @@ arraycmp(const Py_ssize_t *a1, const Py_ssize_t *a2, const Py_ssize_t *shape,
{
Py_ssize_t i;
- if (ndim == 1 && shape && shape[0] == 1) {
- /* This is for comparing strides: For example, the array
- [175], shape=[1], strides=[-5] is considered contiguous. */
- return 1;
- }
for (i = 0; i < ndim; i++) {
+ if (shape && shape[i] <= 1) {
+ /* strides can differ if the dimension is less than 2 */
+ continue;
+ }
if (a1[i] != a2[i]) {
return 0;
}
@@ -2544,7 +2558,7 @@ result:
PyBuffer_Release(&v1);
PyBuffer_Release(&v2);
- ret = equal ? Py_True : Py_False;
+ ret = equal ? Py_True : Py_False;
Py_INCREF(ret);
return ret;
}
@@ -2555,30 +2569,35 @@ is_contiguous(PyObject *self, PyObject *args)
PyObject *obj;
PyObject *order;
PyObject *ret = NULL;
- Py_buffer view;
+ Py_buffer view, *base;
char ord;
if (!PyArg_ParseTuple(args, "OO", &obj, &order)) {
return NULL;
}
- if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
- PyErr_SetString(PyExc_TypeError,
- "is_contiguous: object does not implement the buffer "
- "protocol");
+ ord = get_ascii_order(order);
+ if (ord == CHAR_MAX) {
return NULL;
}
- ord = get_ascii_order(order);
- if (ord == CHAR_MAX) {
- goto release;
+ if (NDArray_Check(obj)) {
+ /* Skip the buffer protocol to check simple etc. buffers directly. */
+ base = &((NDArrayObject *)obj)->head->base;
+ ret = PyBuffer_IsContiguous(base, ord) ? Py_True : Py_False;
+ }
+ else {
+ if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
+ PyErr_SetString(PyExc_TypeError,
+ "is_contiguous: object does not implement the buffer "
+ "protocol");
+ return NULL;
+ }
+ ret = PyBuffer_IsContiguous(&view, ord) ? Py_True : Py_False;
+ PyBuffer_Release(&view);
}
- ret = PyBuffer_IsContiguous(&view, ord) ? Py_True : Py_False;
Py_INCREF(ret);
-
-release:
- PyBuffer_Release(&view);
return ret;
}