diff options
author | Michael Droettboom <mdboom@gmail.com> | 2014-09-19 12:46:49 -0400 |
---|---|---|
committer | Michael Droettboom <mdboom@gmail.com> | 2014-09-19 14:57:55 -0400 |
commit | 0c6fd4875acc733165ca71301c661535aaebed93 (patch) | |
tree | cb193ca2a7944b10db9450f1b5aa17b758a9dd38 | |
parent | 4083883228d61a3b571dec640185b5a5d983bf59 (diff) | |
download | numpy-0c6fd4875acc733165ca71301c661535aaebed93.tar.gz |
Fix strides when creating Python buffer
-rw-r--r-- | numpy/core/src/multiarray/buffer.c | 26 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 16 |
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): |