8000 BUG __numpy_ufunc__ gives unexpected TypeError with subclasses by mhvk · Pull Request #4815 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

BUG __numpy_ufunc__ gives unexpected TypeError with subclasses #4815

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Don't give over precedence to subclass if self has __numpy_ufunc__
  • Loading branch information
mhvk committed Jun 20, 2014
commit 26675c80a7ad711c8671bcb0bce558f450167780
6 changes: 4 additions & 2 deletions numpy/core/src/multiarray/number.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include <Python.h>
#include "structmember.h"

/*#include <stdio.h>*/
/* #include <stdio.h> */
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
#define _MULTIARRAYMODULE
#include "numpy/arrayobject.h"
Expand Down Expand Up @@ -135,7 +135,7 @@ needs_right_binop_forward(PyObject *self, PyObject *other,
*/
return 0;
< 8000 /td> }
if (has_ufunc_attr(other) &&
if (!has_ufunc_attr(self) && has_ufunc_attr(other) &&
PyObject_HasAttrString(other, right_name)) {
return 1;
}
Expand Down Expand Up @@ -337,6 +337,8 @@ PyArray_GenericInplaceUnaryFunction(PyArrayObject *m1, PyObject *op)
static PyObject *
array_add(PyArrayObject *m1, PyObject *m2)
{
float f;
f = 1./0.;
GIVE_UP_IF_HAS_RIGHT_BINOP(m1, m2, "__add__", "__radd__", 0);
return PyArray_GenericBinaryFunction(m1, m2, n_ops.add);
}
Expand Down
36 changes: 29 additions & 7 deletions numpy/core/tests/test_multiarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -1763,25 +1763,47 @@ def __rop__(self, *other):
err_msg = "%r %r" % (op_name, arr,)

# Check that ndarray op gives up if it sees a non-subclass
# with __numpy_ufunc__ and does not have `__numpy_ufunc__`
# itself.
if not isinstance(obj, arr.__class__):
assert_equal(getattr(arr, op_name)(obj),
NotImplemented, err_msg=err_msg)
if hasattr(arr, '__numpy_ufunc__'):
if op_name != rop_name:
# skip for __eq__, __ne__, since those give
# unrelated DeprecationWarning
assert_raises(AssertionError,
getattr(arr, op_name), obj)
else:
assert_equal(getattr(arr, op_name)(obj),
NotImplemented, err_msg=err_msg)

# Check that the Python binops have priority
assert_equal(op(obj, arr), "op", err_msg=err_msg)
if op_name == rop_name:
assert_equal(op(arr, obj), "op", err_msg=err_msg)
# skip ufunc call for __eq__, __ne__, since those give
# unrelated DeprecationWarning
if not hasattr(arr, '__numpy_ufunc__'):
assert_equal(op(arr, obj), "op", err_msg=err_msg)
else:
assert_equal(op(arr, obj), "rop", err_msg=err_msg)
if hasattr(arr, '__numpy_ufunc__'):
assert_raises(AssertionError, op, arr, obj)
else:
assert_equal(op(arr, obj), "rop", err_msg=err_msg)

# Check that Python binops have priority also for in-place ops
if has_iop:
assert_equal(getattr(arr, iop_name)(obj),
NotImplemented, err_msg=err_msg)
if hasattr(arr, '__numpy_ufunc__'):
assert_raises(AssertionError,
getattr(arr, iop_name), obj)
else:
assert_equal(getattr(arr, iop_name)(obj),
NotImplemented, err_msg=err_msg)
if op_name != "__pow__":
# inplace pow requires the other object to be
# integer-like?
assert_equal(iop(arr, obj), "rop", err_msg=err_msg)
if hasattr(arr, '__numpy_ufunc__'):
assert_raises(AssertionError, iop, arr, obj)
else:
assert_equal(iop(arr, obj), "rop", err_msg=err_msg)

# Check that ufunc call __numpy_ufunc__ normally
if np_op is not None:
Expand Down
0