Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/release/upcoming_changes/26268.expired.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Scalars and 0D arrays are disallowed for `numpy.nonzero` and `numpy.ndarray.nonzero`.
43 changes: 7 additions & 36 deletions numpy/_core/src/multiarray/item_selection.c
Original file line number Diff line number Diff line change
Expand Up @@ -2797,6 +2797,13 @@ NPY_NO_EXPORT PyObject *
PyArray_Nonzero(PyArrayObject *self)
{
int i, ndim = PyArray_NDIM(self);
if (ndim == 0) {
PyErr_SetString(PyExc_ValueError,
"Calling nonzero on 0d arrays is not allowed. "
"Use np.atleast_1d(scalar).nonzero() instead.");
Comment thread
rgommers marked this conversation as resolved.
Outdated
return NULL;
}

PyArrayObject *ret = NULL;
PyObject *ret_tuple;
npy_intp ret_dims[2];
Expand All @@ -2818,42 +2825,6 @@ PyArray_Nonzero(PyArrayObject *self)
nonzero = PyDataType_GetArrFuncs(dtype)->nonzero;
needs_api = PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI);

/* Special case - nonzero(zero_d) is nonzero(atleast_1d(zero_d)) */
if (ndim == 0) {
char const* msg;
if (PyArray_ISBOOL(self)) {
msg =
"Calling nonzero on 0d arrays is deprecated, as it behaves "
"surprisingly. Use `atleast_1d(cond).nonzero()` if the old "
"behavior was intended. If the context of this warning is of "
"the form `arr[nonzero(cond)]`, just use `arr[cond]`.";
}
else {
msg =
"Calling nonzero on 0d arrays is deprecated, as it behaves "
"surprisingly. Use `atleast_1d(arr).nonzero()` if the old "
"behavior was intended.";
}
if (DEPRECATE(msg) < 0) {
return NULL;
}

static npy_intp const zero_dim_shape[1] = {1};
static npy_intp const zero_dim_strides[1] = {0};

Py_INCREF(PyArray_DESCR(self)); /* array creation steals reference */
PyArrayObject *self_1d = (PyArrayObject *)PyArray_NewFromDescrAndBase(
Py_TYPE(self), PyArray_DESCR(self),
1, zero_dim_shape, zero_dim_strides, PyArray_BYTES(self),
PyArray_FLAGS(self), (PyObject *)self, (PyObject *)self);
if (self_1d == NULL) {
return NULL;
}
ret_tuple = PyArray_Nonzero(self_1d);
Py_DECREF(self_1d);
return ret_tuple;
}

/*
* First count the number of non-zeros in 'self'.
*/
Expand Down
7 changes: 0 additions & 7 deletions numpy/_core/tests/test_deprecations.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,6 @@ def test_deprecate_unparsable_string(self, invalid_str):
assert_array_equal(res, x)


class TestNonZero(_DeprecationTestCase):
# 2019-05-26, 1.17.0
def test_zerod(self):
self.assert_deprecated(lambda: np.nonzero(np.array(0)))
self.assert_deprecated(lambda: np.nonzero(np.array(1)))


class TestToString(_DeprecationTestCase):
# 2020-03-06 1.19.0
message = re.escape("tostring() is deprecated. Use tobytes() instead.")
Expand Down
16 changes: 6 additions & 10 deletions numpy/_core/tests/test_numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -1567,16 +1567,12 @@ def test_nonzero_trivial(self):
assert_equal(np.count_nonzero(np.array([1], dtype='?')), 1)
assert_equal(np.nonzero(np.array([1])), ([0],))

def test_nonzero_zerod(self):
assert_equal(np.count_nonzero(np.array(0)), 0)
assert_equal(np.count_nonzero(np.array(0, dtype='?')), 0)
with assert_warns(DeprecationWarning):
assert_equal(np.nonzero(np.array(0)), ([],))

assert_equal(np.count_nonzero(np.array(1)), 1)
assert_equal(np.count_nonzero(np.array(1, dtype='?')), 1)
with assert_warns(DeprecationWarning):
assert_equal(np.nonzero(np.array(1)), ([0],))
def test_nonzero_zerodim(self):
err_msg = "Calling nonzero on 0d arrays is not allowed"
with assert_raises_regex(ValueError, err_msg):
np.nonzero(np.array(0))
with assert_raises_regex(ValueError, err_msg):
np.array(1).nonzero()

def test_nonzero_onedim(self):
x = np.array([1, 0, 2, -1, 0, 0, 8])
Expand Down
3 changes: 0 additions & 3 deletions tools/ci/array-api-skips.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ array_api_tests/test_signatures.py::test_func_signature[reshape]
array_api_tests/test_signatures.py::test_func_signature[argsort]
array_api_tests/test_signatures.py::test_func_signature[sort]

# nonzero for 0D should error
array_api_tests/test_searching_functions.py::test_nonzero_zerodim_error

# TODO: check why in CI `inspect.signature(np.vecdot)` returns (*arg, **kwarg)
# instead of raising ValueError. mtsokol: couldn't reproduce locally
array_api_tests/test_signatures.py::test_func_signature[vecdot]