[Numpy-discussion] __array_priority__ ignored if __array__ is present

Thomas Robitaille thomas.robitaille at gmail.com
Thu May 30 15:28:42 EDT 2013


Hi Frederic,

On 16 May 2013 15:58, Frédéric Bastien <nouiz at nouiz.org> wrote:
> I looked yesterday rapidly in the code and didn't find the reason (I don't
> know it well, that is probably why).
>
> But last night I think of one possible cause. I found this code 2 times in
> the file core/src/umath/ufunc_object.c:
>
>     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;
>             }
>     }
>     }
>
> It is this code that will call _has_reflected_op() function. The if
> condition is:
>
> dtypes[1]->type_num == NPY_OBJECT
>
>
> I wouldn't be surprised if dtypes[1] isn't NPY_OBJECT when you implement
> __array__.
>
> dtypes is set with those line:
>
>     retval = ufunc->type_resolver(ufunc, casting,
>                             op, type_tup, dtypes);

Thanks for looking into this - should this be considered a bug?

Tom

>
>
> HTH
>
> Fred
>
>
>
> On Thu, May 16, 2013 at 9:19 AM, Thomas Robitaille
> <thomas.robitaille at gmail.com> wrote:
>>
>> Hi everyone,
>>
>> (this was posted as part of another topic, but since it was unrelated,
>> I'm reposting as a separate thread)
>>
>> I've also been having issues with __array_priority__ - the following
>> code behaves differently for __mul__ and __rmul__:
>>
>> """
>> import numpy as np
>>
>>
>> class TestClass(object):
>>
>>     def __init__(self, input_array):
>>         self.array = input_array
>>
>>     def __mul__(self, other):
>>         print "Called __mul__"
>>
>>     def __rmul__(self, other):
>>         print "Called __rmul__"
>>
>>     def __array_wrap__(self, out_arr, context=None):
>>         print "Called __array_wrap__"
>>         return TestClass(out_arr)
>>
>>     def __array__(self):
>>         print "Called __array__"
>>         return np.array(self.array)
>> """
>>
>> with output:
>>
>> """
>> In [7]: a = TestClass([1,2,3])
>>
>> In [8]: print type(np.array([1,2,3]) * a)
>> Called __array__
>> Called __array_wrap__
>> <class '__main__.TestClass'>
>>
>> In [9]: print type(a * np.array([1,2,3]))
>> Called __mul__
>> <type 'NoneType'>
>> """
>>
>> Is this also an oversight? I opened a ticket for it a little while ago:
>>
>> https://github.com/numpy/numpy/issues/3164
>>
>> Any ideas?
>>
>> Thanks!
>> Tom
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion at scipy.org
>> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>
>
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
>



More information about the NumPy-Discussion mailing list