From b491cc8916e7ac1bf974fab8c2f9b65b17a90457 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Sat, 9 Jan 2016 16:24:44 -0500 Subject: [PATCH 1/3] TST: Ensure `dot` fails correctly if array types cannot be coerced into a common type. --- numpy/core/tests/test_multiarray.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 04e09d37fea0..881c9c783891 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -2041,6 +2041,13 @@ def __numpy_ufunc__(self, ufunc, method, pos, inputs, **kwargs): assert_raises(TypeError, np.dot, b, c) assert_raises(TypeError, c.dot, b) + def test_dot_type_mismatch(self): + c = 1. + A = np.array((1,1), dtype='i,i') + + assert_raises(ValueError, np.dot, c, A) + assert_raises(TypeError, np.dot, A, c) + def test_diagonal(self): a = np.arange(12).reshape((3, 4)) assert_equal(a.diagonal(), [0, 5, 10]) From 67592d34fa0bc09fb20686cc76565e3153c0c958 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Sat, 9 Jan 2016 16:26:40 -0500 Subject: [PATCH 2/3] TST: Ensure `inner` fails correctly if array types cannot be coerced into a common type. --- numpy/core/tests/test_multiarray.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 881c9c783891..c9e610cbff12 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -4832,6 +4832,13 @@ def test_matmul_inplace(): class TestInner(TestCase): + def test_inner_type_mismatch(self): + c = 1. + A = np.array((1,1), dtype='i,i') + + assert_raises(TypeError, np.inner, c, A) + assert_raises(TypeError, np.inner, A, c) + def test_inner_scalar_and_vector(self): for dt in np.typecodes['AllInteger'] + np.typecodes['AllFloat'] + '?': sca = np.array(3, dtype=dt)[()] From bab118da49f051aecf35296bb9d8a00edd5b4198 Mon Sep 17 00:00:00 2001 From: John Kirkham Date: Sun, 10 Jan 2016 17:11:28 -0500 Subject: [PATCH 3/3] BUG: Clear error before constructing error message using calls to `PyObject_Repr`. Also, do a better job of handling any errors raised while constructing the error message. --- numpy/core/src/multiarray/ctors.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index e23cbe3c9db2..2b8c35234304 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -1926,14 +1926,34 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags) /* Raise an error if the casting rule isn't followed */ if (!PyArray_CanCastArrayTo(arr, newtype, casting)) { PyObject *errmsg; + PyArray_Descr *arr_descr = NULL; + PyObject *arr_descr_repr = NULL; + PyObject *newtype_repr = NULL; + PyErr_Clear(); errmsg = PyUString_FromString("Cannot cast array data from "); - PyUString_ConcatAndDel(&errmsg, - PyObject_Repr((PyObject *)PyArray_DESCR(arr))); + arr_descr = PyArray_DESCR(arr); + if (arr_descr == NULL) { + Py_DECREF(newtype); + Py_DECREF(errmsg); + return NULL; + } + arr_descr_repr = PyObject_Repr((PyObject *)arr_descr); + if (arr_descr_repr == NULL) { + Py_DECREF(newtype); + Py_DECREF(errmsg); + return NULL; + } + PyUString_ConcatAndDel(&errmsg, arr_descr_repr); PyUString_ConcatAndDel(&errmsg, PyUString_FromString(" to ")); - PyUString_ConcatAndDel(&errmsg, - PyObject_Repr((PyObject *)newtype)); + newtype_repr = PyObject_Repr((PyObject *)newtype); + if (newtype_repr == NULL) { + Py_DECREF(newtype); + Py_DECREF(errmsg); + return NULL; + } + PyUString_ConcatAndDel(&errmsg, newtype_repr); PyUString_ConcatAndDel(&errmsg, PyUString_FromFormat(" according to the rule %s", npy_casting_to_string(casting)));