8000 MAINT: add missing test cases (from review) · numpy/numpy@11fa976 · GitHub
[go: up one dir, main page]

Skip to content

Commit 11fa976

Browse files
committed
MAINT: add missing test cases (from review)
1 parent 217e2a7 commit 11fa976

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

numpy/core/src/umath/ufunc_object.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6096,6 +6096,7 @@ ufunc_at__slow_iter(PyUFuncObject *ufunc, NPY_ARRAYMETHOD_FLAGS flags,
60966096
-1, NULL, NULL, buffersize);
60976097

60986098
if (iter_buffer == NULL) {
6099+
/* will fail only on memory allocation errors */
60996100
for (int i = 0; i < 3; i++) {
61006101
Py_XDECREF(array_operands[i]);
61016102
}
@@ -6104,6 +6105,7 @@ ufunc_at__slow_iter(PyUFuncObject *ufunc, NPY_ARRAYMETHOD_FLAGS flags,
61046105

61056106
iternext = NpyIter_GetIterNext(iter_buffer, NULL);
61066107
if (iternext == NULL) {
6108+
/* can not really happen, iter_buffer creation is tightly controlled */
61076109
NpyIter_Deallocate(iter_buffer);
61086110
for (int i = 0; i < 3; i++) {
61096111
Py_XDECREF(array_operands[i]);
@@ -6185,7 +6187,7 @@ ufunc_at__slow_iter(PyUFuncObject *ufunc, NPY_ARRAYMETHOD_FLAGS flags,
61856187
NpyIter_Deallocate(iter_buffer);
61866188
for (int i = 0; i < 3; i++) {
61876189
Py_XDECREF(array_operands[i]);
6188-
}
6190+
}
61896191
return res;
61906192
}
61916193

@@ -6249,6 +6251,12 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args)
62496251
"second operand needed for ufunc");
62506252
return NULL;
62516253
}
6254+
6255+
if (ufunc->nin == 1 && op2 != NULL) {
6256+
PyErr_SetString(PyExc_ValueError,
6257+
"second operand provided when ufunc is unary");
6258+
return NULL;
6259+
}
62526260
errval = PyUFunc_CheckOverride(ufunc, "at",
62536261
args, NULL, NULL, 0, NULL, &override);
62546262

@@ -6299,6 +6307,7 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args)
62996307
if ((iter->subspace != NULL) && (iter->consec)) {
63006308
PyArray_MapIterSwapAxes(iter, &op2_array, 0);
63016309
if (op2_array == NULL) {
6310+
/* only on memory allocation failure */
63026311
goto fail;
63036312
}
63046313
}
@@ -6314,13 +6323,16 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args)
63146323
if ((iter2 = (PyArrayIterObject *)\
63156324
PyArray_BroadcastToShape((PyObject *)op2_array,
63166325
iter->dimensions, iter->nd))==NULL) {
6326+
/* only on memory allocation failures */
63176327
goto fail;
63186328
}
63196329
}
63206330

63216331
PyArrayMethodObject *ufuncimpl = NULL;
63226332

63236333
{
6334+
/* Do all the dtype handling and find the correct ufuncimpl */
6335+
63246336
PyArrayObject *tmp_operands[3] = {NULL, NULL, NULL};
63256337
PyArray_DTypeMeta *signature[3] = {NULL, NULL, NULL};
63266338
PyArray_DTypeMeta *operand_DTypes[3] = {NULL, NULL, NULL};
@@ -6346,7 +6358,6 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args)
63466358
operand_DTypes[2] = operand_DTypes[0];
63476359
Py_INCREF(operand_DTypes[2]);
63486360

6349-
nop = 3;
63506361
if (allow_legacy_promotion && ((PyArray_NDIM(op1_array) == 0)
63516362
!= (PyArray_NDIM(op2_array) == 0))) {
63526363
/* both are legacy and only one is 0-D: force legacy */
@@ -6358,7 +6369,6 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args)
63586369
operand_DTypes[1] = operand_DTypes[0];
63596370
Py_INCREF(operand_DTypes[1]);
63606371
tmp_operands[2] = NULL;
6361-
nop = 2;
63626372
}
63636373

63646374
ufuncimpl = promote_and_get_ufuncimpl(ufunc, tmp_operands, signature,

numpy/core/tests/test_ufunc.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,15 +1926,26 @@ def __rmul__(self, other):
19261926
@pytest.mark.parametrize("a", (
19271927
np.arange(10, dtype=int),
19281928
np.arange(10, dtype=_rational_tests.rational),
1929-
1930-
))
1931-
def test_inplace_fancy_indexing(self, a):
1929+
))
1930+
def test_ufunc_at(self, a):
19321931
np.add.at(a, [2, 5, 2], 1)
19331932
assert_equal(a, [0, 1, 4, 3, 4, 6, 6, 7, 8, 9])
19341933

1934+
with pytest.raises(ValueError):
1935+
# missing second operand
1936+
np.add.at(a, [2, 5, 3])
1937+
19351938
np.negative.at(a, [2, 5, 3])
19361939
assert_equal(a, [0, 1, -4, -3, 4, -6, 6, 7, 8, 9])
19371940

1941+
with pytest.raises(ValueError):
1942+
# extraneous second operand
1943+
np.negative.at(a, [2, 5, 3], [1, 2, 3])
1944+
1945+
with pytest.raises(ValueError):
1946+
# second operand cannot be converted to an array
1947+
np.add.at(a, [2, 5, 3], [[1, 2], 1])
1948+
19381949
# reset a
19391950
a = np.arange(10)
19401951
b = np.array([100, 100, 100])
@@ -2082,6 +2093,12 @@ def test_at_not_none_signature(self):
20822093
a = np.array([[[1, 2], [3, 4]]])
20832094
assert_raises(TypeError, np.linalg._umath_linalg.det.at, a, [0])
20842095

2096+
def test_at_no_loop_for_op(self):
2097+
# str dtype does not have a ufunc loop for np.add
2098+
arr = np.ones(10, dtype=str)
2099+
with pytest.raises(np.core._exceptions._UFuncNoLoopError):
2100+
np.add.at(arr, [0, 1], [0, 1])
2101+
20852102
def test_reduce_arguments(self):
20862103
f = np.add.reduce
20872104
d = np.ones((5,2), dtype=int)

0 commit comments

Comments
 (0)
0