Change in __array_priority__ behavior breaks code.
Hi All, The following change breaks existing code, my polynomial classes for example. File: numpy/core/src/umath/ufunc_object.c Previous Code: /* * FAIL with NotImplemented if the other object has * the __r<op>__ method and has __array_priority__ as * an attribute (signalling it can handle ndarray's) * and is not already an ndarray or a subtype of the same type. */ if ((arg_types[1] == PyArray_OBJECT) && (loop->ufunc->nin==2) && (loop->ufunc->nout == 1)) { PyObject *_obj = PyTuple_GET_ITEM(args, 1); if (!PyArray_CheckExact(_obj) /* If both are same subtype of object arrays, then proceed */ && !(Py_TYPE(_obj) == Py_TYPE(PyTuple_GET_ITEM(args, 0))) && PyObject_HasAttrString(_obj, "__array_priority__") && _has_reflected_op(_obj, loop->ufunc->name)) { loop->notimplemented = 1; return nargs; } } Current Code: /* * FAIL with NotImplemented if the other object has * the __r<op>__ method and has __array_priority__ as * an attribute (signalling it can handle ndarray's) * and is not already an ndarray or a subtype of the same type. */ if (nin == 2 && nout == 1 && dtypes[1]->type_num == NPY_OBJECT) { PyObject *_obj = PyTuple_GET_ITEM(args, 1); if (!PyArray_CheckExact(_obj)) { double self_prio, other_prio; self_prio = PyArray_GetPriority(PyTuple_GET_ITEM(args, 0), NPY_SCALAR_PRIORITY); other_prio = PyArray_GetPriority(_obj, NPY_SCALAR_PRIORITY); if (self_prio < other_prio && _has_reflected_op(_obj, ufunc_name)) { retval = -2; goto fail; } } } The difference is that the previous code ignored the value of the priority. I think that is the best thing to do, as trying to use the priority to decide the priority between objects that aren't ndarray or subclasses of ndarray is likely to lead to problems. Because there is no central repository of priorities from which to allocate them, the priorities are essentially arbitrary. I think the old approach makes more sense in this context. Even in the old code the restriction to a single output seems excessive and will fail with divmod. I thought I'd raise this issue on the list because it does reflect a design decision that should be made at some point. For the current development branch I think the code should be reverted simply because it breaks backward compatibility. Chuck
participants (1)
-
Charles R Harris