[Numpy-discussion] zeros_like and friends shouldn't use ndarray.__new__(type(a), ...)

Jim Porter porterj at alum.rit.edu
Thu May 13 19:34:11 EDT 2010


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



More information about the NumPy-Discussion mailing list