summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Droettboom <mdboom@gmail.com>2014-09-19 12:46:49 -0400
committerMichael Droettboom <mdboom@gmail.com>2014-09-19 14:57:55 -0400
commit0c6fd4875acc733165ca71301c661535aaebed93 (patch)
treecb193ca2a7944b10db9450f1b5aa17b758a9dd38
parent4083883228d61a3b571dec640185b5a5d983bf59 (diff)
downloadnumpy-0c6fd4875acc733165ca71301c661535aaebed93.tar.gz
Fix strides when creating Python buffer
-rw-r--r--numpy/core/src/multiarray/buffer.c26
-rw-r--r--numpy/core/tests/test_multiarray.py16
2 files changed, 42 insertions, 0 deletions
diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c
index ea1a885ed..e410f12b2 100644
--- a/numpy/core/src/multiarray/buffer.c
+++ b/numpy/core/src/multiarray/buffer.c
@@ -628,6 +628,8 @@ array_getbuffer(PyObject *obj, Py_buffer *view, int flags)
{
PyArrayObject *self;
_buffer_info_t *info = NULL;
+ int i;
+ Py_ssize_t sd;
self = (PyArrayObject*)obj;
@@ -702,6 +704,30 @@ array_getbuffer(PyObject *obj, Py_buffer *view, int flags)
}
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
view->strides = info->strides;
+
+#ifdef NPY_RELAXED_STRIDES_CHECKING
+ /*
+ * If NPY_RELAXED_STRIDES_CHECKING is on, the array may be
+ * contiguous, but it won't look that way to Python when it
+ * tries to determine contiguity by looking at the strides
+ * (since one of the elements may be -1). In that case, just
+ * regenerate strides from shape.
+ */
+ if (PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)) {
+ sd = view->itemsize;
+ for (i = view->ndim-1; i >= 0; --i) {
+ view->strides[i] = sd;
+ sd *= view->shape[i];
+ }
+ }
+ else if (PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)) {
+ sd = view->itemsize;
+ for (i = 0; i < view->ndim; ++i) {
+ view->strides[i] = sd;
+ sd *= view->shape[i];
+ }
+ }
+#endif
}
else {
view->strides = NULL;
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 27f908fe4..a9b2d751f 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -4258,6 +4258,22 @@ class TestNewBufferProtocol(object):
x3 = np.arange(dt3.itemsize, dtype=np.int8).view(dt3)
self._check_roundtrip(x3)
+ def test_relaxed_strides(self):
+ # Test that relaxed strides are converted to non-relaxed
+ x = np.zeros((5, 10), dtype=">f4")
+
+ # Add an extra dimension in such a way that the strides will
+ # contain -1 markers
+ c = np.array([x])
+ assert memoryview(c).strides == (200, 40, 4)
+
+ # Writing C-contiguous data to a BytesIO buffer should work
+ fd = io.BytesIO()
+ fd.write(c.data)
+
+ fortran = c.T
+ assert memoryview(fortran).strides == (4, 40, 200)
+
class TestArrayAttributeDeletion(object):