Skip to content

Commit

Permalink
Merge pull request numpy#25672 from ngoldbaum/fix-scalar-from-string-…
Browse files Browse the repository at this point in the history
…overflow
  • Loading branch information
ngoldbaum committed Feb 2, 2024
2 parents 08eecff + 4a7d492 commit b1c3f9b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
18 changes: 17 additions & 1 deletion numpy/_core/src/multiarray/arraytypes.c.src
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,23 @@ NPY_NO_EXPORT int
@type@ temp; /* ensures alignment */

#if @is_int@
if (PyLong_Check(op)) {
int is_pylong = PyLong_Check(op);
// array objects do not get checked for overflow after conversion to a
// pyint because the default fill value for integer masked arrays is
// array(999999), which overflows for (u)int8 and (u)int16.
if (!(is_pylong || PyArray_Check(op))) {
PyObject* ret = PyNumber_Long(op);
if (ret == NULL) {
return -1;
}
op = ret;
if (@TYPE@_safe_pyint_setitem(op, &temp) < 0) {
Py_DECREF(op);
return -1;
}
Py_DECREF(op);
}
else if (is_pylong) {
/*
* When weak promotion is enabled (using NEP 50) we also use more
* strict parsing of integers: All out-of-bound Python integer
Expand Down
31 changes: 31 additions & 0 deletions numpy/_core/tests/test_nep50_promotions.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,34 @@ def test_integer_integer_comparison(comp):

# Test that the NumPy comparison ufuncs work with large Python integers
assert comp(2**200, -2**200) == comp(2**200, -2**200, dtype=object)


def create_with_scalar(sctype, value):
return sctype(value)


def create_with_array(sctype, value):
return np.array([value], dtype=sctype)


@pytest.mark.parametrize("sctype",
[np.int8, np.int16, np.int32, np.int64,
np.uint8, np.uint16, np.uint32, np.uint64])
@pytest.mark.parametrize("create", [create_with_scalar, create_with_array])
def test_oob_creation(sctype, create):
iinfo = np.iinfo(sctype)

with pytest.raises(OverflowError):
create(sctype, iinfo.min - 1)

with pytest.raises(OverflowError):
create(sctype, iinfo.max + 1)

with pytest.raises(OverflowError):
create(sctype, str(iinfo.min - 1))

with pytest.raises(OverflowError):
create(sctype, str(iinfo.max + 1))

assert create(sctype, iinfo.min) == iinfo.min
assert create(sctype, iinfo.max) == iinfo.max
4 changes: 4 additions & 0 deletions numpy/f2py/tests/test_array_from_pyobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,10 @@ def test_in_cache_from_2casttype_failure(self):
continue
if t.elsize >= self.type.elsize:
continue
is_int = np.issubdtype(t.dtype, np.integer)
if is_int and int(self.num2seq[0]) > np.iinfo(t.dtype).max:
# skip test if num2seq would trigger an overflow error
continue
obj = np.array(self.num2seq, dtype=t.dtype)
shape = (len(self.num2seq), )
try:
Expand Down

0 comments on commit b1c3f9b

Please sign in to comment.