zeros_like and friends shouldn't use ndarray.__new__(type(a), ...)

Ok, let's try sending this message again, since it looks like I can't send from gmane... (See discussion on python-list at http://permalink.gmane.org/gmane.comp.python.general/661328 for context) numpy.zeros_like contains the following code: def zeros_like(a): if isinstance(a, ndarray): res = ndarray.__new__(type(a), a.shape, a.dtype, order=a.flags.fnc) res.fill(0) return res ... This is a problem because basetype.__new__(subtype, ...) raises an exception when subtype is defined from C (specifically, when Py_TPFLAGS_HEAPTYPE is not set). There's a check in Objects/typeobject.c in tp_new_wrapper that disallows this (you can grep for "is not safe" to find there the exception is raised). The end result is that it's impossible to use zeros_like, ones_like or empty_like with ndarray subtypes defined in C. While I'm still not sure why Python needs this check in general, Robert Kern pointed out that the problem can be fixed pretty easily in NumPy by changing zeros_like and friends to something like this (with some modifications from me): def zeros_like(a): if isinstance(a, ndarray): res = numpy.zeros(a.shape, a.dtype, order=a.flags.fnc) res = res.view(type(a)) res.__array_finalize__(a) return res ... - Jim

Ping? On 5/13/2010 6:34 PM, Jim Porter wrote:
Ok, let's try sending this message again, since it looks like I can't send from gmane...
(See discussion on python-list at http://permalink.gmane.org/gmane.comp.python.general/661328 for context)
numpy.zeros_like contains the following code:
def zeros_like(a): if isinstance(a, ndarray): res = ndarray.__new__(type(a), a.shape, a.dtype, order=a.flags.fnc) res.fill(0) return res ...
This is a problem because basetype.__new__(subtype, ...) raises an exception when subtype is defined from C (specifically, when Py_TPFLAGS_HEAPTYPE is not set). There's a check in Objects/typeobject.c in tp_new_wrapper that disallows this (you can grep for "is not safe" to find there the exception is raised).
The end result is that it's impossible to use zeros_like, ones_like or empty_like with ndarray subtypes defined in C.
While I'm still not sure why Python needs this check in general, Robert Kern pointed out that the problem can be fixed pretty easily in NumPy by changing zeros_like and friends to something like this (with some modifications from me):
def zeros_like(a): if isinstance(a, ndarray): res = numpy.zeros(a.shape, a.dtype, order=a.flags.fnc) res = res.view(type(a)) res.__array_finalize__(a) return res ...
- Jim
participants (2)
-
James Porter
-
Jim Porter