summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/umath/loops.c.src22
-rw-r--r--numpy/core/tests/test_multiarray.py4
-rw-r--r--numpy/core/tests/test_ufunc.py6
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)