Skip to content

Commit

Permalink
BUG: Errors thrown by 0d arrays in setitem are silenced and replaced
Browse files Browse the repository at this point in the history
Fixes gh-8461
  • Loading branch information
eric-wieser committed Sep 23, 2017
1 parent 8899616 commit 8e26a5d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
17 changes: 13 additions & 4 deletions numpy/core/src/multiarray/arraytypes.c.src
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@
#include <limits.h>
#include <assert.h>

/* check for sequences, but ignore the types numpy considers scalars */
static NPY_INLINE npy_bool
PySequence_NoString_Check(PyObject *op) {
return
PySequence_Check(op) &&
!PyString_Check(op) &&
!PyUnicode_Check(op) &&
!PyArray_IsZeroDim(op);
}

/*
*****************************************************************************
** PYTHON TYPES TO C TYPES **
Expand Down Expand Up @@ -223,8 +233,7 @@ static int
if (PyErr_Occurred()) {
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
if (PySequence_Check(op) && !PyString_Check(op) &&
!PyUnicode_Check(op)) {
if (PySequence_NoString_Check(op)) {
PyErr_SetString(PyExc_ValueError,
"setting an array element with a sequence.");
Py_DECREF(type);
Expand Down Expand Up @@ -461,7 +470,7 @@ UNICODE_setitem(PyObject *op, void *ov, void *vap)
return convert_to_scalar_and_retry(op, ov, vap, UNICODE_setitem);
}

if (!PyBytes_Check(op) && !PyUnicode_Check(op) && PySequence_Check(op)) {
if (PySequence_NoString_Check(op)) {
PyErr_SetString(PyExc_ValueError,
"setting an array element with a sequence");
return -1;
Expand Down Expand Up @@ -552,7 +561,7 @@ STRING_setitem(PyObject *op, void *ov, void *vap)
return convert_to_scalar_and_retry(op, ov, vap, STRING_setitem);
}

if (!PyBytes_Check(op) && !PyUnicode_Check(op) && PySequence_Check(op)) {
if (PySequence_NoString_Check(op)) {
PyErr_SetString(PyExc_ValueError,
"setting an array element with a sequence");
return -1;
Expand Down
25 changes: 24 additions & 1 deletion numpy/ma/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

__author__ = "Pierre GF Gerard-Marchant"

import sys
import warnings
import pickle
import operator
Expand All @@ -20,7 +21,7 @@
import numpy.core.fromnumeric as fromnumeric
import numpy.core.umath as umath
from numpy.testing import (
run_module_suite, assert_raises, assert_warns, suppress_warnings
run_module_suite, assert_raises, assert_warns, suppress_warnings, dec
)
from numpy import ndarray
from numpy.compat import asbytes, asbytes_nested
Expand Down Expand Up @@ -4836,6 +4837,28 @@ def test_immutable(self):
assert_raises(ValueError, operator.setitem, view.data, (), 1)
assert_raises(ValueError, operator.setitem, view.mask, (), False)

@dec.knownfailureif(sys.version_info.major == 2, "See gh-9751")
def test_coercion_int(self):
a_i = np.zeros((), int)
assert_raises(MaskError, operator.setitem, a_i, (), np.ma.masked)

def test_coercion_float(self):
a_f = np.zeros((), float)
assert_warns(UserWarning, operator.setitem, a_f, (), np.ma.masked)
assert_(np.isnan(a_f[()]))

@dec.knownfailureif(True, "See gh-9750")
def test_coercion_unicode(self):
a_u = np.zeros((), 'U10')
a_u[()] = np.ma.masked
assert_equal(a_u[()], u'--')

@dec.knownfailureif(True, "See gh-9750")
def test_coercion_bytes(self):
a_b = np.zeros((), 'S10')
a_b[()] = np.ma.masked
assert_equal(a_b[()], b'--')


def test_masked_array():
a = np.ma.array([0, 1, 2, 3], mask=[0, 0, 1, 0])
Expand Down

0 comments on commit 8e26a5d

Please sign in to comment.