diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2014-07-06 10:06:50 -0600 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2014-07-06 10:06:50 -0600 |
commit | 8dba040fcc26c21c982d162b03948a0b21b65535 (patch) | |
tree | 45a923ecf86d899054a62a0dba515de2d99d4443 /numpy | |
parent | 81242f627582e04c000b73e52bc9b4067b0f478d (diff) | |
parent | 9c4d48c3c27584e8a555b5e55d1634089db7a01a (diff) | |
download | numpy-8dba040fcc26c21c982d162b03948a0b21b65535.tar.gz |
Merge pull request #4804 from seberg/fancy-ass-1d
WIP: Fix matplotlib, etc. errors
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/multiarray/mapping.c | 89 | ||||
-rw-r--r-- | numpy/core/tests/test_indexing.py | 10 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 8 |
3 files changed, 101 insertions, 6 deletions
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c index e2b8ef700..bf4851519 100644 --- a/numpy/core/src/multiarray/mapping.c +++ b/numpy/core/src/multiarray/mapping.c @@ -1656,6 +1656,58 @@ array_assign_item(PyArrayObject *self, Py_ssize_t i, PyObject *op) /* + * This fallback takes the old route of `arr.flat[index] = values` + * for one dimensional `arr`. The route can sometimes fail slightly + * different (ValueError instead of IndexError), in which case we + * warn users about the change. But since it does not actually care *at all* + * about shapes, it should only fail for out of bound indexes or + * casting errors. + */ +NPY_NO_EXPORT int +attempt_1d_fallback(PyArrayObject *self, PyObject *ind, PyObject *op) +{ + PyObject *err = PyErr_Occurred(); + PyArrayIterObject *self_iter = NULL; + + Py_INCREF(err); + PyErr_Clear(); + + self_iter = (PyArrayIterObject *)PyArray_IterNew((PyObject *)self); + if (self_iter == NULL) { + goto fail; + } + if (iter_ass_subscript(self_iter, ind, op) < 0) { + goto fail; + } + + Py_XDECREF((PyObject *)self_iter); + Py_DECREF(err); + + if (DEPRECATE( + "assignment will raise an error in the future, most likely " + "because your index result shape does not match the value array " + "shape. You can use `arr.flat[index] = values` to keep the old " + "behaviour.") < 0) { + return -1; + } + return 0; + + fail: + if (!PyErr_ExceptionMatches(err)) { + PyObject *err, *val, *tb; + PyErr_Fetch(&err, &val, &tb); + DEPRECATE_FUTUREWARNING( + "assignment exception type will change in the future"); + PyErr_Restore(err, val, tb); + } + + Py_XDECREF((PyObject *)self_iter); + Py_DECREF(err); + return -1; +} + + +/* * General assignment with python indexing objects. */ static int @@ -1746,9 +1798,20 @@ array_assign_subscript(PyArrayObject *self, PyObject *ind, PyObject *op) Py_INCREF(op); tmp_arr = (PyArrayObject *)op; } + if (array_assign_boolean_subscript(self, (PyArrayObject *)indices[0].object, tmp_arr, NPY_CORDER) < 0) { + /* + * Deprecated case. The old boolean indexing seemed to have some + * check to allow wrong dimensional boolean arrays in all cases. + */ + if (PyArray_NDIM(tmp_arr) > 1) { + if (attempt_1d_fallback(self, indices[0].object, tmp_arr) < 0) { + goto fail; + } + goto success; + } goto fail; } goto success; @@ -1899,14 +1962,36 @@ array_assign_subscript(PyArrayObject *self, PyObject *ind, PyObject *op) tmp_arr, descr); if (mit == NULL) { - goto fail; + /* + * This is a deprecated special case to allow non-matching shapes + * for the index and value arrays. + */ + if (index_type != HAS_FANCY || index_num != 1) { + /* This is not a "flat like" 1-d special case */ + goto fail; + } + if (attempt_1d_fallback(self, indices[0].object, op) < 0) { + goto fail; + } + goto success; } if (tmp_arr == NULL) { /* Fill extra op */ if (PyArray_CopyObject(mit->extra_op, op) < 0) { - goto fail; + /* + * This is a deprecated special case to allow non-matching shapes + * for the index and value arrays. + */ + if (index_type != HAS_FANCY || index_num != 1) { + /* This is not a "flat like" 1-d special case */ + goto fail; + } + if (attempt_1d_fallback(self, indices[0].object, op) < 0) { + goto fail; + } + goto success; } } diff --git a/numpy/core/tests/test_indexing.py b/numpy/core/tests/test_indexing.py index 6b0b0a0b5..44928b264 100644 --- a/numpy/core/tests/test_indexing.py +++ b/numpy/core/tests/test_indexing.py @@ -402,8 +402,14 @@ class TestBroadcastedAssignments(TestCase): # Too large and not only ones. assert_raises(ValueError, assign, a, s_[...], np.ones((2, 1))) - assert_raises(ValueError, assign, a, s_[[1, 2, 3],], np.ones((2, 1))) - assert_raises(ValueError, assign, a, s_[[[1], [2]],], np.ones((2,2,1))) + + with warnings.catch_warnings(): + # Will be a ValueError as well. + warnings.simplefilter("error", DeprecationWarning) + assert_raises(DeprecationWarning, assign, a, s_[[1, 2, 3],], + np.ones((2, 1))) + assert_raises(DeprecationWarning, assign, a, s_[[[1], [2]],], + np.ones((2,2,1))) def test_simple_broadcasting_errors(self): diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 9f40d7b54..316ee33d3 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -756,8 +756,12 @@ class TestRegression(TestCase): s = np.ones(10, dtype=float) x = np.array((15,), dtype=float) def ia(x, s, v): x[(s>0)]=v - self.assertRaises(ValueError, ia, x, s, np.zeros(9, dtype=float)) - self.assertRaises(ValueError, ia, x, s, np.zeros(11, dtype=float)) + # After removing deprecation, the following is are ValueErrors. + # This might seem odd as compared to the value error below. This + # is due to the fact that the new code always use "nonzero" logic + # and the boolean special case is not taken. + self.assertRaises(IndexError, ia, x, s, np.zeros(9, dtype=float)) + self.assertRaises(IndexError, ia, x, s, np.zeros(11, dtype=float)) # Old special case (different code path): self.assertRaises(ValueError, ia, x.flat, s, np.zeros(9, dtype=float)) |