segfaults when passing ndarray subclass to ufunc with out=None

I am seeing some really strange behavior when I try to pass an ndarray subclass and out=None to numpy's ufuncs. This example will reproduce the problem with svn numpy, the first print statement yields 1 as expected, the second yields "<type 'builtin_function_or_method'>" and the third yields a segmentation fault: import numpy as np class MyArray(np.ndarray): __array_priority__ = 20 def __new__(cls): return np.asarray(1).view(cls).copy() def __repr__(self): return 'my_array' __str__ = __repr__ def __mul__(self, other): return super(MyArray, self).__mul__(other) def __rmul__(self, other): return super(MyArray, self).__rmul__(other) mine = MyArray() print np.multiply(1, 1, None) x = np.multiply(mine, mine, None) print type(x) print x Darren

On Sun, Feb 8, 2009 at 12:49 PM, Darren Dale <dsdale24@gmail.com> wrote:
I am seeing some really strange behavior when I try to pass an ndarray subclass and out=None to numpy's ufuncs. This example will reproduce the problem with svn numpy, the first print statement yields 1 as expected, the second yields "<type 'builtin_function_or_method'>" and the third yields a segmentation fault:
import numpy as np
class MyArray(np.ndarray):
__array_priority__ = 20
def __new__(cls): return np.asarray(1).view(cls).copy()
def __repr__(self): return 'my_array'
__str__ = __repr__
def __mul__(self, other): return super(MyArray, self).__mul__(other)
def __rmul__(self, other): return super(MyArray, self).__rmul__(other)
mine = MyArray() print np.multiply(1, 1, None) x = np.multiply(mine, mine, None) print type(x) print x
I think I might have found a fix for this. The following patch allows my script to run without a segfault: $ svn diff Index: umath_ufunc_object.inc =================================================================== --- umath_ufunc_object.inc (revision 6566) +++ umath_ufunc_object.inc (working copy) @@ -3212,13 +3212,10 @@ output_wrap[i] = wrap; if (j < nargs) { obj = PyTuple_GET_ITEM(args, j); - if (obj == Py_None) { - continue; - } if (PyArray_CheckExact(obj)) { output_wrap[i] = Py_None; } - else { + else if (obj != Py_None) { PyObject *owrap = PyObject_GetAttrString(obj,"__array_wrap__"); incref = 0; if (!(owrap) || !(PyCallable_Check(owrap))) { That call to continue skipped this bit of code in the loop, which is apparently important: if (incref) { Py_XINCREF(output_wrap[i]); } I've tested the trunk on 64 bit linux, with and without this patch applied, and I get the same result in both cases: 1 known failure, 11 skips. Is there any chance someone could consider applying this patch before 1.3 ships? Darren
participants (1)
-
Darren Dale