diff options
-rw-r--r-- | numpy/core/tests/test_deprecations.py | 207 | ||||
-rw-r--r-- | numpy/core/tests/test_indexing.py | 211 |
2 files changed, 196 insertions, 222 deletions
diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py index c5f69fc00..3e76409c5 100644 --- a/numpy/core/tests/test_deprecations.py +++ b/numpy/core/tests/test_deprecations.py @@ -115,213 +115,6 @@ class _DeprecationTestCase(object): exceptions=tuple(), args=args, kwargs=kwargs) -class TestFloatNonIntegerArgumentDeprecation(_DeprecationTestCase): - """ - These test that ``DeprecationWarning`` is given when you try to use - non-integers as arguments to for indexing and slicing e.g. ``a[0.0:5]`` - and ``a[0.5]``, or other functions like ``array.reshape(1., -1)``. - - After deprecation, changes need to be done inside conversion_utils.c - in PyArray_PyIntAsIntp and possibly PyArray_IntpConverter. - In iterators.c the function slice_GetIndices could be removed in favor - of its python equivalent and in mapping.c the function _tuple_of_integers - can be simplified (if ``np.array([1]).__index__()`` is also deprecated). - - As for the deprecation time-frame: via Ralf Gommers, - - "Hard to put that as a version number, since we don't know if the - version after 1.8 will be 6 months or 2 years after. I'd say 2 - years is reasonable." - - I interpret this to mean 2 years after the 1.8 release. Possibly - giving a PendingDeprecationWarning before that (which is visible - by default) - - """ - message = "using a non-integer number instead of an integer " \ - "will result in an error in the future" - - def test_indexing(self): - a = np.array([[[5]]]) - - assert_raises(IndexError, lambda: a[0.0]) - assert_raises(IndexError, lambda: a[0, 0.0]) - assert_raises(IndexError, lambda: a[0.0, 0]) - assert_raises(IndexError, lambda: a[0.0,:]) - assert_raises(IndexError, lambda: a[:, 0.0]) - assert_raises(IndexError, lambda: a[:, 0.0,:]) - assert_raises(IndexError, lambda: a[0.0,:,:]) - assert_raises(IndexError, lambda: a[0, 0, 0.0]) - assert_raises(IndexError, lambda: a[0.0, 0, 0]) - assert_raises(IndexError, lambda: a[0, 0.0, 0]) - assert_raises(IndexError, lambda: a[-1.4]) - assert_raises(IndexError, lambda: a[0, -1.4]) - assert_raises(IndexError, lambda: a[-1.4, 0]) - assert_raises(IndexError, lambda: a[-1.4,:]) - assert_raises(IndexError, lambda: a[:, -1.4]) - assert_raises(IndexError, lambda: a[:, -1.4,:]) - assert_raises(IndexError, lambda: a[-1.4,:,:]) - assert_raises(IndexError, lambda: a[0, 0, -1.4]) - assert_raises(IndexError, lambda: a[-1.4, 0, 0]) - assert_raises(IndexError, lambda: a[0, -1.4, 0]) - - # Test that the slice parameter deprecation warning doesn't mask - # the scalar index warning. - assert_raises(IndexError, lambda: a[0.0:, 0.0]) - assert_raises(IndexError, lambda: a[0.0:, 0.0,:]) - - def test_valid_indexing(self): - a = np.array([[[5]]]) - assert_not_deprecated = self.assert_not_deprecated - - assert_not_deprecated(lambda: a[np.array([0])]) - assert_not_deprecated(lambda: a[[0, 0]]) - assert_not_deprecated(lambda: a[:, [0, 0]]) - assert_not_deprecated(lambda: a[:, 0,:]) - assert_not_deprecated(lambda: a[:,:,:]) - - def test_slicing(self): - a = np.array([[5]]) - - # start as float. - assert_raises(IndexError, lambda: a[0.0:]) - assert_raises(IndexError, lambda: a[0:, 0.0:2]) - assert_raises(IndexError, lambda: a[0.0::2, :0]) - assert_raises(IndexError, lambda: a[0.0:1:2,:]) - assert_raises(IndexError, lambda: a[:, 0.0:]) - # stop as float. - assert_raises(IndexError, lambda: a[:0.0]) - assert_raises(IndexError, lambda: a[:0, 1:2.0]) - assert_raises(IndexError, lambda: a[:0.0:2, :0]) - assert_raises(IndexError, lambda: a[:0.0,:]) - assert_raises(IndexError, lambda: a[:, 0:4.0:2]) - # step as float. - assert_raises(IndexError, lambda: a[::1.0]) - assert_raises(IndexError, lambda: a[0:, :2:2.0]) - assert_raises(IndexError, lambda: a[1::4.0, :0]) - assert_raises(IndexError, lambda: a[::5.0,:]) - assert_raises(IndexError, lambda: a[:, 0:4:2.0]) - # mixed. - assert_raises(IndexError, lambda: a[1.0:2:2.0]) - assert_raises(IndexError, lambda: a[1.0::2.0]) - assert_raises(IndexError, lambda: a[0:, :2.0:2.0]) - assert_raises(IndexError, lambda: a[1.0:1:4.0, :0]) - assert_raises(IndexError, lambda: a[1.0:5.0:5.0,:]) - assert_raises(IndexError, lambda: a[:, 0.4:4.0:2.0]) - # should still get the DeprecationWarning if step = 0. - assert_raises(IndexError, lambda: a[::0.0]) - - def test_valid_slicing(self): - a = np.array([[[5]]]) - assert_not_deprecated = self.assert_not_deprecated - - assert_not_deprecated(lambda: a[::]) - assert_not_deprecated(lambda: a[0:]) - assert_not_deprecated(lambda: a[:2]) - assert_not_deprecated(lambda: a[0:2]) - assert_not_deprecated(lambda: a[::2]) - assert_not_deprecated(lambda: a[1::2]) - assert_not_deprecated(lambda: a[:2:2]) - assert_not_deprecated(lambda: a[1:2:2]) - - def test_non_integer_argument_deprecations(self): - a = np.array([[5]]) - - assert_raises(TypeError, np.reshape, a, (1., 1., -1)) - assert_raises(TypeError, np.reshape, a, (np.array(1.), -1)) - assert_raises(TypeError, np.take, a, [0], 1.) - assert_raises(TypeError, np.take, a, [0], np.float64(1.)) - - def test_non_integer_sequence_multiplication(self): - # Numpy scalar sequence multiply should not work with non-integers - def mult(a, b): - return a * b - - assert_raises(TypeError, mult, [1], np.float_(3)) - self.assert_not_deprecated(mult, args=([1], np.int_(3))) - - def test_reduce_axis_float_index(self): - d = np.zeros((3,3,3)) - assert_raises(TypeError, np.min, d, 0.5) - assert_raises(TypeError, np.min, d, (0.5, 1)) - assert_raises(TypeError, np.min, d, (1, 2.2)) - assert_raises(TypeError, np.min, d, (.2, 1.2)) - - -class TestBooleanArgumentDeprecation(_DeprecationTestCase): - """This tests that using a boolean as integer argument/indexing is - deprecated. - - This should be kept in sync with TestFloatNonIntegerArgumentDeprecation - and like it is handled in PyArray_PyIntAsIntp. - """ - message = "using a boolean instead of an integer " \ - "will result in an error in the future" - - def test_bool_as_int_argument(self): - a = np.array([[[1]]]) - - assert_raises(TypeError, np.reshape, a, (True, -1)) - assert_raises(TypeError, np.reshape, a, (np.bool_(True), -1)) - # Note that operator.index(np.array(True)) does not work, a boolean - # array is thus also deprecated, but not with the same message: - assert_raises(TypeError, operator.index, np.array(True)) - assert_raises(TypeError, np.take, args=(a, [0], False)) - assert_raises(IndexError, lambda: a[False:True:True]) - assert_raises(IndexError, lambda: a[False, 0]) - assert_raises(IndexError, lambda: a[False, 0, 0]) - - -class TestArrayToIndexDeprecation(_DeprecationTestCase): - """This tests that creating an an index from an array is deprecated - if the array is not 0d. - - This can probably be deprecated somewhat faster then the integer - deprecations. The deprecation period started with NumPy 1.8. - For deprecation this needs changing of array_index in number.c - """ - message = "converting an array with ndim \> 0 to an index will result " \ - "in an error in the future" - - def test_array_to_index_deprecation(self): - # This drops into the non-integer deprecation, which is ignored here, - # so no exception is expected. The raising is effectively tested above. - a = np.array([[[1]]]) - - assert_raises(TypeError, operator.index, np.array([1])) - assert_raises(TypeError, np.reshape, a, (a, -1)) - assert_raises(TypeError, np.take, a, [0], a) - - # Check slicing. Normal indexing checks arrays specifically. - assert_raises(IndexError, lambda: a[a:a:a]) - - -class TestNonIntegerArrayLike(_DeprecationTestCase): - """Tests that array likes, i.e. lists give a deprecation warning - when they cannot be safely cast to an integer. - """ - message = "non integer \(and non boolean\) array-likes will not be " \ - "accepted as indices in the future" - - def test_basic(self): - a = np.arange(10) - assert_raises(IndexError, a.__getitem__, [0.5, 1.5]) - assert_raises(IndexError, a.__getitem__, (['1', '2'],)) - - self.assert_not_deprecated(a.__getitem__, ([],)) - - -class TestMultipleEllipsisDeprecation(_DeprecationTestCase): - message = "an index can only have a single Ellipsis \(`...`\); replace " \ - "all but one with slices \(`:`\)." - - def test_basic(self): - a = np.arange(10) - assert_raises(IndexError, lambda : a[..., ...]) - assert_raises(IndexError, a.__getitem__, ((Ellipsis,) * 2,)) - assert_raises(IndexError, a.__getitem__, ((Ellipsis,) * 3,)) - - class TestBooleanUnaryMinusDeprecation(_DeprecationTestCase): """Test deprecation of unary boolean `-`. While + and * are well defined, unary - is not and even a corrected form seems to have diff --git a/numpy/core/tests/test_indexing.py b/numpy/core/tests/test_indexing.py index ef876a622..c985e4dd0 100644 --- a/numpy/core/tests/test_indexing.py +++ b/numpy/core/tests/test_indexing.py @@ -3,6 +3,7 @@ from __future__ import division, absolute_import, print_function import sys import warnings import functools +import operator import numpy as np from numpy.core.multiarray_tests import array_indexing @@ -21,6 +22,69 @@ except ImportError: class TestIndexing(TestCase): + def test_index_no_floats(self): + a = np.array([[[5]]]) + + assert_raises(IndexError, lambda: a[0.0]) + assert_raises(IndexError, lambda: a[0, 0.0]) + assert_raises(IndexError, lambda: a[0.0, 0]) + assert_raises(IndexError, lambda: a[0.0,:]) + assert_raises(IndexError, lambda: a[:, 0.0]) + assert_raises(IndexError, lambda: a[:, 0.0,:]) + assert_raises(IndexError, lambda: a[0.0,:,:]) + assert_raises(IndexError, lambda: a[0, 0, 0.0]) + assert_raises(IndexError, lambda: a[0.0, 0, 0]) + assert_raises(IndexError, lambda: a[0, 0.0, 0]) + assert_raises(IndexError, lambda: a[-1.4]) + assert_raises(IndexError, lambda: a[0, -1.4]) + assert_raises(IndexError, lambda: a[-1.4, 0]) + assert_raises(IndexError, lambda: a[-1.4,:]) + assert_raises(IndexError, lambda: a[:, -1.4]) + assert_raises(IndexError, lambda: a[:, -1.4,:]) + assert_raises(IndexError, lambda: a[-1.4,:,:]) + assert_raises(IndexError, lambda: a[0, 0, -1.4]) + assert_raises(IndexError, lambda: a[-1.4, 0, 0]) + assert_raises(IndexError, lambda: a[0, -1.4, 0]) + assert_raises(IndexError, lambda: a[0.0:, 0.0]) + assert_raises(IndexError, lambda: a[0.0:, 0.0,:]) + + def test_slicing_no_floats(self): + a = np.array([[5]]) + + # start as float. + assert_raises(IndexError, lambda: a[0.0:]) + assert_raises(IndexError, lambda: a[0:, 0.0:2]) + assert_raises(IndexError, lambda: a[0.0::2, :0]) + assert_raises(IndexError, lambda: a[0.0:1:2,:]) + assert_raises(IndexError, lambda: a[:, 0.0:]) + # stop as float. + assert_raises(IndexError, lambda: a[:0.0]) + assert_raises(IndexError, lambda: a[:0, 1:2.0]) + assert_raises(IndexError, lambda: a[:0.0:2, :0]) + assert_raises(IndexError, lambda: a[:0.0,:]) + assert_raises(IndexError, lambda: a[:, 0:4.0:2]) + # step as float. + assert_raises(IndexError, lambda: a[::1.0]) + assert_raises(IndexError, lambda: a[0:, :2:2.0]) + assert_raises(IndexError, lambda: a[1::4.0, :0]) + assert_raises(IndexError, lambda: a[::5.0,:]) + assert_raises(IndexError, lambda: a[:, 0:4:2.0]) + # mixed. + assert_raises(IndexError, lambda: a[1.0:2:2.0]) + assert_raises(IndexError, lambda: a[1.0::2.0]) + assert_raises(IndexError, lambda: a[0:, :2.0:2.0]) + assert_raises(IndexError, lambda: a[1.0:1:4.0, :0]) + assert_raises(IndexError, lambda: a[1.0:5.0:5.0,:]) + assert_raises(IndexError, lambda: a[:, 0.4:4.0:2.0]) + # should still get the DeprecationWarning if step = 0. + assert_raises(IndexError, lambda: a[::0.0]) + + def test_index_no_array_to_index(self): + # No non-scalar arrays. + a = np.array([[[1]]]) + + assert_raises(IndexError, lambda: a[a:a:a]) + def test_none_index(self): # `None` index adds newaxis a = np.array([1, 2, 3]) @@ -36,8 +100,8 @@ class TestIndexing(TestCase): assert_(isinstance(a[()], np.int_)) def test_same_kind_index_casting(self): - # Indexes should be cast with same-kind and not safe, even if - # that is somewhat unsafe. So test various different code paths. + # Indexes should be cast with same-kind and not safe, even if that + # is somewhat unsafe. So test various different code paths. index = np.arange(5) u_index = index.astype(np.uintp) arr = np.arange(10) @@ -75,7 +139,8 @@ class TestIndexing(TestCase): [4, 5, 6], [7, 8, 9]]) assert_equal(a[...], a) - assert_(a[...].base is a) # `a[...]` was `a` in numpy <1.9.) + # `a[...]` was `a` in numpy <1.9. + assert_(a[...].base is a) # Slicing with ellipsis can skip an # arbitrary number of dimensions @@ -709,16 +774,18 @@ class TestMultiIndexingAutomated(TestCase): indx = np.array(indx, dtype=np.intp) in_indices[i] = indx elif indx.dtype.kind != 'b' and indx.dtype.kind != 'i': - raise IndexError('arrays used as indices must be of integer (or boolean) type') + raise IndexError('arrays used as indices must be of ' + 'integer (or boolean) type') if indx.ndim != 0: no_copy = False ndim += 1 fancy_dim += 1 if arr.ndim - ndim < 0: - # we can't take more dimensions then we have, not even for 0-d arrays. - # since a[()] makes sense, but not a[(),]. We will raise an error - # later on, unless a broadcasting error occurs first. + # we can't take more dimensions then we have, not even for 0-d + # arrays. since a[()] makes sense, but not a[(),]. We will + # raise an error later on, unless a broadcasting error occurs + # first. raise IndexError if ndim == 0 and None not in in_indices: @@ -726,7 +793,8 @@ class TestMultiIndexingAutomated(TestCase): return arr.copy(), no_copy if ellipsis_pos is not None: - in_indices[ellipsis_pos:ellipsis_pos+1] = [slice(None, None)] * (arr.ndim - ndim) + in_indices[ellipsis_pos:ellipsis_pos+1] = ([slice(None, None)] * + (arr.ndim - ndim)) for ax, indx in enumerate(in_indices): if isinstance(indx, slice): @@ -769,10 +837,10 @@ class TestMultiIndexingAutomated(TestCase): if indx >= arr.shape[ax] or indx < -arr.shape[ax]: raise IndexError if indx.ndim == 0: - # The index is a scalar. This used to be two fold, but if fancy - # indexing was active, the check was done later, possibly - # after broadcasting it away (1.7. or earlier). Now it is always - # done. + # The index is a scalar. This used to be two fold, but if + # fancy indexing was active, the check was done later, + # possibly after broadcasting it away (1.7. or earlier). + # Now it is always done. if indx >= arr.shape[ax] or indx < - arr.shape[ax]: raise IndexError if len(indices) > 0 and indices[-1][0] == 'f' and ax != ellipsis_pos: @@ -781,9 +849,9 @@ class TestMultiIndexingAutomated(TestCase): indices[-1].append(indx) else: # We have a fancy index that is not after an existing one. - # NOTE: A 0-d array triggers this as well, while - # one may expect it to not trigger it, since a scalar - # would not be considered fancy indexing. + # NOTE: A 0-d array triggers this as well, while one may + # expect it to not trigger it, since a scalar would not be + # considered fancy indexing. num_fancy += 1 indices.append(['f', indx]) @@ -993,6 +1061,119 @@ class TestMultiIndexingAutomated(TestCase): for index in self.complex_indices: self._check_single_index(a, index) +class TestFloatNonIntegerArgument(TestCase): + """ + These test that ``TypeError`` is raised when you try to use + non-integers as arguments to for indexing and slicing e.g. ``a[0.0:5]`` + and ``a[0.5]``, or other functions like ``array.reshape(1., -1)``. + + """ + def test_valid_indexing(self): + # These should raise no errors. + a = np.array([[[5]]]) + + a[np.array([0])] + a[[0, 0]] + a[:, [0, 0]] + a[:, 0,:] + a[:,:,:] + + def test_valid_slicing(self): + # These should raise no errors. + a = np.array([[[5]]]) + + a[::] + a[0:] + a[:2] + a[0:2] + a[::2] + a[1::2] + a[:2:2] + a[1:2:2] + + def test_non_integer_argument_errors(self): + a = np.array([[5]]) + + assert_raises(TypeError, np.reshape, a, (1., 1., -1)) + assert_raises(TypeError, np.reshape, a, (np.array(1.), -1)) + assert_raises(TypeError, np.take, a, [0], 1.) + assert_raises(TypeError, np.take, a, [0], np.float64(1.)) + + def test_non_integer_sequence_multiplication(self): + # Numpy scalar sequence multiply should not work with non-integers + def mult(a, b): + return a * b + + assert_raises(TypeError, mult, [1], np.float_(3)) + # following should be OK + mult([1], np.int_(3)) + + def test_reduce_axis_float_index(self): + d = np.zeros((3,3,3)) + assert_raises(TypeError, np.min, d, 0.5) + assert_raises(TypeError, np.min, d, (0.5, 1)) + assert_raises(TypeError, np.min, d, (1, 2.2)) + assert_raises(TypeError, np.min, d, (.2, 1.2)) + + +class TestBooleanArgumentErrors(TestCase): + """Using a boolean as integer argument/indexing is an error. + + """ + def test_bool_as_int_argument(self): + a = np.array([[[1]]]) + + assert_raises(TypeError, np.reshape, a, (True, -1)) + assert_raises(TypeError, np.reshape, a, (np.bool_(True), -1)) + # Note that operator.index(np.array(True)) does not work, a boolean + # array is thus also deprecated, but not with the same message: + assert_raises(TypeError, operator.index, np.array(True)) + assert_raises(TypeError, np.take, args=(a, [0], False)) + assert_raises(IndexError, lambda: a[False:True:True]) + assert_raises(IndexError, lambda: a[False, 0]) + assert_raises(IndexError, lambda: a[False, 0, 0]) + + +class TestArrayToIndexDeprecation(TestCase): + """Creating an an index from array not 0-D is an error. + + """ + def test_array_to_index_error(self): + # so no exception is expected. The raising is effectively tested above. + a = np.array([[[1]]]) + + assert_raises(TypeError, operator.index, np.array([1])) + assert_raises(TypeError, np.reshape, a, (a, -1)) + assert_raises(TypeError, np.take, a, [0], a) + + +class TestNonIntegerArrayLike(TestCase): + """Tests that array_likes only valid if can safely cast to integer. + + For instance, lists give IndexError when they cannot be safely cast to + an integer. + + """ + def test_basic(self): + a = np.arange(10) + + assert_raises(IndexError, a.__getitem__, [0.5, 1.5]) + assert_raises(IndexError, a.__getitem__, (['1', '2'],)) + + # The following is valid + a.__getitem__([]) + + +class TestMultipleEllipsisError(TestCase): + """An index can only have a single ellipsis. + + """ + def test_basic(self): + a = np.arange(10) + assert_raises(IndexError, lambda: a[..., ...]) + assert_raises(IndexError, a.__getitem__, ((Ellipsis,) * 2,)) + assert_raises(IndexError, a.__getitem__, ((Ellipsis,) * 3,)) + class TestCApiAccess(TestCase): def test_getitem(self): |