diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2018-05-27 13:40:20 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-27 13:40:20 -0600 |
commit | 69458b02956d39082014573eb0350ae3eb3436ee (patch) | |
tree | 35a05b19a67c4aa67b40a71627eb35470479c796 | |
parent | 7d7c71ccae98c448f120d42f372bb2d0d3f10f6a (diff) | |
parent | a10b4270d4b3f538254698874560d645c0525dc5 (diff) | |
download | numpy-69458b02956d39082014573eb0350ae3eb3436ee.tar.gz |
Merge pull request #9686 from eric-wieser/force-tuple
DEP: Deprecate non-tuple nd-indices
-rw-r--r-- | doc/release/1.15.0-notes.rst | 7 | ||||
-rw-r--r-- | doc/source/reference/arrays.indexing.rst | 17 | ||||
-rw-r--r-- | numpy/core/src/multiarray/mapping.c | 17 | ||||
-rw-r--r-- | numpy/core/tests/test_deprecations.py | 16 |
4 files changed, 49 insertions, 8 deletions
diff --git a/doc/release/1.15.0-notes.rst b/doc/release/1.15.0-notes.rst index 04a188c65..23e0284c4 100644 --- a/doc/release/1.15.0-notes.rst +++ b/doc/release/1.15.0-notes.rst @@ -46,6 +46,13 @@ Deprecations * `np.ma.load`, `np.ma.dump` - these functions already failed on python 3, when called with a string. +* Multidimensional indexing with anything but a tuple is + deprecated. This means that code such as ``ind = [slice(None), 0]``, + ``arr[[slice(None), 0]]`` should be changed to ``arr[tuple(ind)]``. This is + necessary to avoid ambiguity in expressions such as ``arr[[[0, 1], [0, 1]]]`` + which currently is interpreted as ``arr[array([0, 1]), array([0, 1])]``. + In future, this will be interpreted as ``arr[array([[0, 1], [0, 1]])]``. + * Direct imports from the following modules is deprecated. All testing related imports should come from `numpy.testing`. * `np.testing.utils` diff --git a/doc/source/reference/arrays.indexing.rst b/doc/source/reference/arrays.indexing.rst index b5a44c22a..ba1bfd312 100644 --- a/doc/source/reference/arrays.indexing.rst +++ b/doc/source/reference/arrays.indexing.rst @@ -29,11 +29,15 @@ dimensions. Basic slicing occurs when *obj* is a :class:`slice` object (constructed by ``start:stop:step`` notation inside of brackets), an integer, or a tuple of slice objects and integers. :const:`Ellipsis` and :const:`newaxis` objects can be interspersed with these as -well. In order to remain backward compatible with a common usage in -Numeric, basic slicing is also initiated if the selection object is -any non-ndarray sequence (such as a :class:`list`) containing :class:`slice` -objects, the :const:`Ellipsis` object, or the :const:`newaxis` object, -but not for integer arrays or other embedded sequences. +well. + +.. deprecated:: 1.15.0 + + In order to remain backward compatible with a common usage in + Numeric, basic slicing is also initiated if the selection object is + any non-ndarray and non-tuple sequence (such as a :class:`list`) containing + :class:`slice` objects, the :const:`Ellipsis` object, or the :const:`newaxis` + object, but not for integer arrays or other embedded sequences. .. index:: triple: ndarray; special methods; getitem @@ -196,7 +200,8 @@ basic slicing that returns a :term:`view`). why this occurs. Also recognize that ``x[[1,2,3]]`` will trigger advanced indexing, - whereas ``x[[1,2,slice(None)]]`` will trigger basic slicing. + whereas due to the deprecated Numeric compatibility mentioned above, + ``x[[1,2,slice(None)]]`` will trigger basic slicing. Integer array indexing ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c index 4b2c6aa5a..42dbc3cce 100644 --- a/numpy/core/src/multiarray/mapping.c +++ b/numpy/core/src/multiarray/mapping.c @@ -293,8 +293,7 @@ unpack_indices(PyObject *index, PyObject **result, npy_intp result_n) if (commit_to_unpack) { /* propagate errors */ if (tmp_obj == NULL) { - multi_DECREF(result, i); - return -1; + goto fail; } } else { @@ -313,6 +312,16 @@ unpack_indices(PyObject *index, PyObject **result, npy_intp result_n) || PySlice_Check(tmp_obj) || tmp_obj == Py_Ellipsis || tmp_obj == Py_None) { + if (DEPRECATE_FUTUREWARNING( + "Using a non-tuple sequence for multidimensional " + "indexing is deprecated; use `arr[tuple(seq)]` " + "instead of `arr[seq]`. In the future this will be " + "interpreted as an array index, `arr[np.array(seq)]`, " + "which will result either in an error or a different " + "result.") < 0) { + i++; /* since loop update doesn't run */ + goto fail; + } commit_to_unpack = 1; } } @@ -328,6 +337,10 @@ unpack_indices(PyObject *index, PyObject **result, npy_intp result_n) multi_DECREF(result, i); return unpack_scalar(index, result, result_n); } + +fail: + multi_DECREF(result, i); + return -1; } /** diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py index 5d59d8226..60a7c72f7 100644 --- a/numpy/core/tests/test_deprecations.py +++ b/numpy/core/tests/test_deprecations.py @@ -134,6 +134,22 @@ class _VisibleDeprecationTestCase(_DeprecationTestCase): warning_cls = np.VisibleDeprecationWarning +class TestNonTupleNDIndexDeprecation(object): + def test_basic(self): + a = np.zeros((5, 5)) + with warnings.catch_warnings(): + warnings.filterwarnings('always') + assert_warns(FutureWarning, a.__getitem__, [[0, 1], [0, 1]]) + assert_warns(FutureWarning, a.__getitem__, [slice(None)]) + + warnings.filterwarnings('error') + assert_raises(FutureWarning, a.__getitem__, [[0, 1], [0, 1]]) + assert_raises(FutureWarning, a.__getitem__, [slice(None)]) + + # a a[[0, 1]] always was advanced indexing, so no error/warning + a[[0, 1]] + + class TestRankDeprecation(_DeprecationTestCase): """Test that np.rank is deprecated. The function should simply be removed. The VisibleDeprecationWarning may become unnecessary. |