diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/umath/loops.c.src | 22 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 4 | ||||
-rw-r--r-- | numpy/core/tests/test_ufunc.py | 6 |
3 files changed, 29 insertions, 3 deletions
diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src index 53afa817b..6accf3065 100644 --- a/numpy/core/src/umath/loops.c.src +++ b/numpy/core/src/umath/loops.c.src @@ -566,16 +566,36 @@ NPY_NO_EXPORT void PyUFunc_O_O_method(char **args, npy_intp *dimensions, npy_intp *steps, void *func) { char *meth = (char *)func; + PyObject *tup = PyTuple_New(0); + if (tup == NULL) { + return; + } UNARY_LOOP { PyObject *in1 = *(PyObject **)ip1; PyObject **out = (PyObject **)op1; - PyObject *ret = PyObject_CallMethod(in1 ? in1 : Py_None, meth, NULL); + PyObject *ret, *func; + func = PyObject_GetAttrString(in1 ? in1 : Py_None, meth); + if (func == NULL || !PyCallable_Check(func)) { + PyObject *exc, *val, *tb; + PyTypeObject *type = in1 ? Py_TYPE(in1) : Py_TYPE(Py_None); + PyErr_Fetch(&exc, &val, &tb); + PyErr_Format(PyExc_TypeError, + "loop of ufunc does not support argument %d of " + "type %s which has no callable %s method", + i, type->tp_name, meth); + npy_PyErr_ChainExceptionsCause(exc, val, tb); + Py_DECREF(tup); + return; + } + ret = PyObject_Call(func, tup, NULL); if (ret == NULL) { + Py_DECREF(tup); return; } Py_XDECREF(*out); *out = ret; } + Py_DECREF(tup); } /*UFUNC_API*/ diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 06cabe2cb..98b923cca 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -3134,8 +3134,8 @@ class TestMethods(object): assert_equal(ac, np.conjugate(a)) a = np.array([1-1j, 1, 2.0, 'f'], object) - assert_raises(AttributeError, lambda: a.conj()) - assert_raises(AttributeError, lambda: a.conjugate()) + assert_raises(TypeError, lambda: a.conj()) + assert_raises(TypeError, lambda: a.conjugate()) def test__complex__(self): dtypes = ['i1', 'i2', 'i4', 'i8', diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py index b52152243..fa62767f6 100644 --- a/numpy/core/tests/test_ufunc.py +++ b/numpy/core/tests/test_ufunc.py @@ -1908,3 +1908,9 @@ class TestUfunc(object): def test_no_doc_string(self): # gh-9337 assert_('\n' not in umt.inner1d_no_doc.__doc__) + + def test_invalid_args(self): + # gh-7961 + exc = pytest.raises(TypeError, np.sqrt, None) + # minimally check the exception text + assert 'loop of ufunc does not support' in str(exc) |