[Numpy-discussion] Change in __array_priority__ behavior breaks code.

Charles R Harris charlesr.harris at gmail.com
Fri Dec 23 23:06:40 EST 2011


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20111223/8f42c5b8/attachment.html>


More information about the NumPy-Discussion mailing list