summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorStefan van der Walt <sjvdwalt@gmail.com>2012-11-06 17:00:07 -0800
committerStefan van der Walt <sjvdwalt@gmail.com>2012-11-06 17:00:07 -0800
commit93be7c0ca93735faac3c9b03b6844a4f9ed90d71 (patch)
tree519002533ffee8c930e0bd8354633991796fb633 /numpy
parent526b7647ad3e0c295340e7b85593364eeadc5686 (diff)
parent0d275f114e49ef5f9569832be2743aa85c4bb4e1 (diff)
downloadnumpy-93be7c0ca93735faac3c9b03b6844a4f9ed90d71.tar.gz
Merge pull request #2702 from seberg/issue2700
BUG: Reshape of 0-sized arrays failed to work without copy.
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/shape.c136
-rw-r--r--numpy/core/tests/test_regression.py5
2 files changed, 46 insertions, 95 deletions
diff --git a/numpy/core/src/multiarray/shape.c b/numpy/core/src/multiarray/shape.c
index 6da07e4cd..482166598 100644
--- a/numpy/core/src/multiarray/shape.c
+++ b/numpy/core/src/multiarray/shape.c
@@ -18,10 +18,6 @@
#include "shape.h"
static int
-_check_ones(PyArrayObject *self, int newnd,
- npy_intp* newdims, npy_intp *strides);
-
-static int
_fix_unknown_dimension(PyArray_Dims *newshape, npy_intp s_original);
static int
@@ -187,6 +183,11 @@ PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims,
if (order == NPY_ANYORDER) {
order = PyArray_ISFORTRAN(self);
}
+ else if (order == NPY_KEEPORDER) {
+ PyErr_SetString(PyExc_ValueError,
+ "order 'K' is not permitted for reshaping");
+ return NULL;
+ }
/* Quick check to make sure anything actually needs to be done */
if (ndim == PyArray_NDIM(self)) {
same = NPY_TRUE;
@@ -203,68 +204,48 @@ PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims,
}
/*
- * Returns a pointer to an appropriate strides array
- * if all we are doing is inserting ones into the shape,
- * or removing ones from the shape
- * or doing a combination of the two
- * In this case we don't need to do anything but update strides and
- * dimensions. So, we can handle non single-segment cases.
+ * fix any -1 dimensions and check new-dimensions against old size
*/
- i = _check_ones(self, ndim, dimensions, newstrides);
- if (i == 0) {
- strides = newstrides;
+ if (_fix_unknown_dimension(newdims, PyArray_SIZE(self)) < 0) {
+ return NULL;
}
- flags = PyArray_FLAGS(self);
-
- if (strides == NULL) {
- /*
- * we are really re-shaping not just adding ones to the shape somewhere
- * fix any -1 dimensions and check new-dimensions against old size
- */
- if (_fix_unknown_dimension(newdims, PyArray_SIZE(self)) < 0) {
- return NULL;
+ /*
+ * sometimes we have to create a new copy of the array
+ * in order to get the right orientation and
+ * because we can't just re-use the buffer with the
+ * data in the order it is in.
+ */
+ if ((order == NPY_CORDER && !PyArray_IS_C_CONTIGUOUS(self)) ||
+ (order == NPY_FORTRANORDER && !PyArray_IS_F_CONTIGUOUS(self))) {
+ int success = 0;
+ success = _attempt_nocopy_reshape(self, ndim, dimensions,
+ newstrides, order);
+ if (success) {
+ /* no need to copy the array after all */
+ strides = newstrides;
}
- /*
- * sometimes we have to create a new copy of the array
- * in order to get the right orientation and
- * because we can't just re-use the buffer with the
- * data in the order it is in.
- */
- if (!(PyArray_ISONESEGMENT(self)) ||
- (((PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS) &&
- order == NPY_FORTRANORDER) ||
- (PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS) &&
- order == NPY_CORDER)) && (PyArray_NDIM(self) > 1))) {
- int success = 0;
- success = _attempt_nocopy_reshape(self, ndim, dimensions,
- newstrides, order);
- if (success) {
- /* no need to copy the array after all */
- strides = newstrides;
- }
- else {
- PyObject *newcopy;
- newcopy = PyArray_NewCopy(self, order);
- if (newcopy == NULL) {
- return NULL;
- }
- incref = NPY_FALSE;
- self = (PyArrayObject *)newcopy;
+ else {
+ PyObject *newcopy;
+ newcopy = PyArray_NewCopy(self, order);
+ if (newcopy == NULL) {
+ return NULL;
}
+ incref = NPY_FALSE;
+ self = (PyArrayObject *)newcopy;
}
+ }
+ /* We always have to interpret the contiguous buffer correctly */
- /* We always have to interpret the contiguous buffer correctly */
-
- /* Make sure the flags argument is set. */
- if (ndim > 1) {
- if (order == NPY_FORTRANORDER) {
- flags &= ~NPY_ARRAY_C_CONTIGUOUS;
- flags |= NPY_ARRAY_F_CONTIGUOUS;
- }
- else {
- flags &= ~NPY_ARRAY_F_CONTIGUOUS;
- flags |= NPY_ARRAY_C_CONTIGUOUS;
- }
+ /* Make sure the flags argument is set. */
+ flags = PyArray_FLAGS(self);
+ if (ndim > 1) {
+ if (order == NPY_FORTRANORDER) {
+ flags &= ~NPY_ARRAY_C_CONTIGUOUS;
+ flags |= NPY_ARRAY_F_CONTIGUOUS;
+ }
+ else {
+ flags &= ~NPY_ARRAY_F_CONTIGUOUS;
+ flags |= NPY_ARRAY_C_CONTIGUOUS;
}
}
@@ -319,41 +300,6 @@ PyArray_Reshape(PyArrayObject *self, PyObject *shape)
return ret;
}
-/* inserts 0 for strides where dimension will be 1 */
-static int
-_check_ones(PyArrayObject *self, int newnd,
- npy_intp* newdims, npy_intp *strides)
-{
- int nd;
- npy_intp *dims;
- npy_bool done=NPY_FALSE;
- int j, k;
-
- nd = PyArray_NDIM(self);
- dims = PyArray_DIMS(self);
-
- for (k = 0, j = 0; !done && (j < nd || k < newnd);) {
- if ((j<nd) && (k<newnd) && (newdims[k] == dims[j])) {
- strides[k] = PyArray_STRIDES(self)[j];
- j++;
- k++;
- }
- else if ((k < newnd) && (newdims[k] == 1)) {
- strides[k] = 0;
- k++;
- }
- else if ((j<nd) && (dims[j] == 1)) {
- j++;
- }
- else {
- done = NPY_TRUE;
- }
- }
- if (done) {
- return -1;
- }
- return 0;
-}
static void
_putzero(char *optr, PyObject *zero, PyArray_Descr *dtype)
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index f46a7ddcf..0f268fce8 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -521,6 +521,11 @@ class TestRegression(TestCase):
a = np.lib.stride_tricks.as_strided(a, shape=(5,), strides=(0,))
assert_(a.reshape(5,1).strides[0] == 0)
+ def test_reshape_zero_size(self, level=rlevel):
+ """Github Issue #2700, setting shape failed for 0-sized arrays"""
+ a = np.ones((0,2))
+ a.shape = (-1,2)
+
def test_repeat_discont(self, level=rlevel):
"""Ticket #352"""
a = np.arange(12).reshape(4,3)[:,2]