summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/array_coercion.c47
-rw-r--r--numpy/core/tests/test_array_coercion.py18
-rw-r--r--numpy/core/tests/test_deprecations.py86
3 files changed, 13 insertions, 138 deletions
diff --git a/numpy/core/src/multiarray/array_coercion.c b/numpy/core/src/multiarray/array_coercion.c
index d55a5752b..ba9118052 100644
--- a/numpy/core/src/multiarray/array_coercion.c
+++ b/numpy/core/src/multiarray/array_coercion.c
@@ -1025,53 +1025,6 @@ PyArray_DiscoverDTypeAndShape_Recursive(
Py_DECREF(arr);
arr = NULL;
}
- else if (curr_dims > 0 && curr_dims != max_dims) {
- /*
- * Deprecated 2020-12-09, NumPy 1.20
- *
- * See https://github.com/numpy/numpy/issues/17965
- * Shapely had objects which are not sequences but did export
- * the array-interface (and so are arguably array-like).
- * Previously numpy would not use array-like information during
- * shape discovery, so that it ended up acting as if this was
- * an (unknown) scalar but with the specified dtype.
- * Thus we ignore "scalars" here, as the value stored in the
- * array should be acceptable.
- */
- if (PyArray_NDIM(arr) > 0 && NPY_UNLIKELY(!PySequence_Check(obj))) {
- if (PyErr_WarnFormat(PyExc_FutureWarning, 1,
- "The input object of type '%s' is an array-like "
- "implementing one of the corresponding protocols "
- "(`__array__`, `__array_interface__` or "
- "`__array_struct__`); but not a sequence (or 0-D). "
- "In the future, this object will be coerced as if it "
- "was first converted using `np.array(obj)`. "
- "To retain the old behaviour, you have to either "
- "modify the type '%s', or assign to an empty array "
- "created with `np.empty(correct_shape, dtype=object)`.",
- Py_TYPE(obj)->tp_name, Py_TYPE(obj)->tp_name) < 0) {
- Py_DECREF(arr);
- return -1;
- }
- /*
- * Strangely enough, even though we threw away the result here,
- * we did use it during descriptor discovery, so promote it:
- */
- if (update_shape(curr_dims, &max_dims, out_shape,
- 0, NULL, NPY_FALSE, flags) < 0) {
- *flags |= FOUND_RAGGED_ARRAY;
- Py_DECREF(arr);
- return max_dims;
- }
- if (!(*flags & DESCRIPTOR_WAS_SET) && handle_promotion(
- out_descr, PyArray_DESCR(arr), fixed_DType, flags) < 0) {
- Py_DECREF(arr);
- return -1;
- }
- Py_DECREF(arr);
- return max_dims;
- }
- }
}
if (arr != NULL) {
/*
diff --git a/numpy/core/tests/test_array_coercion.py b/numpy/core/tests/test_array_coercion.py
index aeddac585..baca076ae 100644
--- a/numpy/core/tests/test_array_coercion.py
+++ b/numpy/core/tests/test_array_coercion.py
@@ -39,9 +39,9 @@ def arraylikes():
yield subclass
class _SequenceLike():
- # We are giving a warning that array-like's were also expected to be
- # sequence-like in `np.array([array_like])`. This can be removed
- # when the deprecation expired (started NumPy 1.20).
+ # Older NumPy versions, sometimes cared whether a protocol array was
+ # also _SequenceLike. This shouldn't matter, but keep it for now
+ # for __array__ and not the others.
def __len__(self):
raise TypeError
@@ -62,7 +62,7 @@ def arraylikes():
yield param(memoryview, id="memoryview")
# Array-interface
- class ArrayInterface(_SequenceLike):
+ class ArrayInterface:
def __init__(self, a):
self.a = a # need to hold on to keep interface valid
self.__array_interface__ = a.__array_interface__
@@ -70,7 +70,7 @@ def arraylikes():
yield param(ArrayInterface, id="__array_interface__")
# Array-Struct
- class ArrayStruct(_SequenceLike):
+ class ArrayStruct:
def __init__(self, a):
self.a = a # need to hold on to keep struct valid
self.__array_struct__ = a.__array_struct__
@@ -654,6 +654,14 @@ class TestArrayLikes:
res = np.array([obj], dtype=object)
assert res[0] is obj
+ @pytest.mark.parametrize("arraylike", arraylikes())
+ @pytest.mark.parametrize("arr", [np.array(0.), np.arange(4)])
+ def test_object_assignment_special_case(self, arraylike, arr):
+ obj = arraylike(arr)
+ empty = np.arange(1, dtype=object)
+ empty[:] = [obj]
+ assert empty[0] is obj
+
def test_0d_generic_special_case(self):
class ArraySubclass(np.ndarray):
def __float__(self):
diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py
index e47a24995..0449b3257 100644
--- a/numpy/core/tests/test_deprecations.py
+++ b/numpy/core/tests/test_deprecations.py
@@ -580,92 +580,6 @@ class TestDeprecateSubarrayDTypeDuringArrayCoercion(_DeprecationTestCase):
self.assert_deprecated(check)
-class TestFutureWarningArrayLikeNotIterable(_DeprecationTestCase):
- # Deprecated 2020-12-09, NumPy 1.20
- warning_cls = FutureWarning
- message = "The input object of type.*but not a sequence"
-
- @pytest.mark.parametrize("protocol",
- ["__array__", "__array_interface__", "__array_struct__"])
- def test_deprecated(self, protocol):
- """Test that these objects give a warning since they are not 0-D,
- not coerced at the top level `np.array(obj)`, but nested, and do
- *not* define the sequence protocol.
-
- NOTE: Tests for the versions including __len__ and __getitem__ exist
- in `test_array_coercion.py` and they can be modified or amended
- when this deprecation expired.
- """
- blueprint = np.arange(10)
- MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol)})
- self.assert_deprecated(lambda: np.array([MyArr()], dtype=object))
-
- @pytest.mark.parametrize("protocol",
- ["__array__", "__array_interface__", "__array_struct__"])
- def test_0d_not_deprecated(self, protocol):
- # 0-D always worked (albeit it would use __float__ or similar for the
- # conversion, which may not happen anymore)
- blueprint = np.array(1.)
- MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol)})
- myarr = MyArr()
-
- self.assert_not_deprecated(lambda: np.array([myarr], dtype=object))
- res = np.array([myarr], dtype=object)
- expected = np.empty(1, dtype=object)
- expected[0] = myarr
- assert_array_equal(res, expected)
-
- @pytest.mark.parametrize("protocol",
- ["__array__", "__array_interface__", "__array_struct__"])
- def test_unnested_not_deprecated(self, protocol):
- blueprint = np.arange(10)
- MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol)})
- myarr = MyArr()
-
- self.assert_not_deprecated(lambda: np.array(myarr))
- res = np.array(myarr)
- assert_array_equal(res, blueprint)
-
- @pytest.mark.parametrize("protocol",
- ["__array__", "__array_interface__", "__array_struct__"])
- def test_strange_dtype_handling(self, protocol):
- """The old code would actually use the dtype from the array, but
- then end up not using the array (for dimension discovery)
- """
- blueprint = np.arange(10).astype("f4")
- MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol),
- "__float__": lambda _: 0.5})
- myarr = MyArr()
-
- # Make sure we warn (and capture the FutureWarning)
- with pytest.warns(FutureWarning, match=self.message):
- res = np.array([[myarr]])
-
- assert res.shape == (1, 1)
- assert res.dtype == "f4"
- assert res[0, 0] == 0.5
-
- @pytest.mark.parametrize("protocol",
- ["__array__", "__array_interface__", "__array_struct__"])
- def test_assignment_not_deprecated(self, protocol):
- # If the result is dtype=object we do not unpack a nested array or
- # array-like, if it is nested at exactly the right depth.
- # NOTE: We actually do still call __array__, etc. but ignore the result
- # in the end. For `dtype=object` we could optimize that away.
- blueprint = np.arange(10).astype("f4")
- MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol),
- "__float__": lambda _: 0.5})
- myarr = MyArr()
-
- res = np.empty(3, dtype=object)
- def set():
- res[:] = [myarr, myarr, myarr]
- self.assert_not_deprecated(set)
- assert res[0] is myarr
- assert res[1] is myarr
- assert res[2] is myarr
-
-
class TestDeprecatedUnpickleObjectScalar(_DeprecationTestCase):
# Deprecated 2020-11-24, NumPy 1.20
"""