[Pyrex] Subclassing numpy.ndarray with Pyrex

Pierre GM pgmdevlist at gmail.com
Mon Feb 5 19:53:27 UTC 2007


All,
I'm a brand new user of Pyrex, who doesn't speak C.
I'd like to use Pyrex to subclass numpy.ndarray. Users of the numpy list 
suggested that I post my problem here as well.

You'll find a sample of the code I'd like to see running below, along with a 
small python script. The c_python.pxd and c_numpy.pxd are straight out the 
doc/pyrex folder of the numpy SVN.

As you can notice, the 'tester.py' segfaults on __array_finalize__ when I 
compute `x+1`. If I remove the comments from __array_finalize__, it crashes 
when processing `x`. Obviously I have a problem of communication with numpy, 
but I can't see where. Moreover, the __array_finalize__ seems to be called 
before the __new__ of my subclass, which is a tad surprising: if I can't 
overload it safely, where am I supposed to initialize the other attributes of 
my subclass ?

Any help/comment will be more than welcome.
Thanks a lot in advance
P.


#############################################
# subnd.pyx
#############################################
# -*- Mode: Python -*-  

cimport c_python
from c_python cimport Py_intptr_t
from c_numpy cimport ndarray, npy_intp, dtype, import_array
import numpy as _N
# NumPy must be initialized
import_array()
#-------------------------------------------------------------------------------
import numpy as _N
cdef class Sub(ndarray):
    cdef readonly object _info
#    cdef ndarray __mask

    def __new__(self, object shape=None, object dtype=None, object 
buffer=None, 
                object order=None):
                #, infodict={}, **extras):
        print "__new__ called"
#        self._info = infodict
        return
    
    def __array_finalize__(self, obj):
        print "__array_finalize__ w/obj %s as %s" % (obj, type(obj))
#        if hasattr(obj, '_info'):
#            self._info = obj._info
#        else:
#            self._info = {}
        return 

    property infoflag:
        def __get__(self):
            return self._info
        def __set__(self, object value):
            self._info = value

def subarray(obj, info={}):
    _obj = <ndarray>_N.asarray(obj)
    print "_obj is %s as %s" % (_obj, type(obj))
    _internal = Sub(shape=_obj.shape, dtype=_obj.dtype, buffer=_obj.data)
    print "_internal set to %s as %s" % (_internal, type(_internal))
    _internal.infoflag = info
    print "_internal infoflag set to %s as %s" % (info, type(info))
    return _internal

##########################################
# tester.py
##########################################
import numpy as N
from subnd import *

lst = [1,2,3]
L = N.asarray(lst)

x = subarray(L)
print "x     :", x, "OK"
print "x+1   :", x+1, "OK"
print "log(x):", N.log(x), "OK"



More information about the Pyrex mailing list