Hello again list, This is the implementation of a class for references in pytables.
Unfortunately, it does not work yet since there is a but in numpy, that I already reported but isn't fixed. And it seems impossible to fix from within pytables. So, here, the implementation of a class reference: ---------------- reference.pyx --------------------------- """ Pyrex special numpy class for HDF5 references Defines one class: reference """ from definitions cimport H5Rcreate, H5R_OBJECT, hobj_ref_t from hdf5Extension cimport File from numpy import typeDict cdef extern from "Python.h": ctypedef struct PyObject: pass ctypedef struct PyTypeObject: object (*tp_new)(PyTypeObject *, PyObject *, PyObject *) object (*tp_alloc)(PyTypeObject *, Py_ssize_t) void (*tp_free)(void *) cdef object PyObject_Init(PyObject *, PyTypeObject *) cdef PyObject *Py_None cdef void Py_INCREF(PyObject *) cdef extern from "numpy/ndarrayobject.h": ctypedef int npy_intp ctypedef object (PyArray_GetItemFunc) (void *, void *) ctypedef int (PyArray_SetItemFunc) (object, void *, void *) ctypedef void (PyArray_CopySwapFunc) (void *, void *, int, void *) ctypedef struct PyArray_ArrFuncs: PyArray_GetItemFunc *getitem PyArray_SetItemFunc *setitem PyArray_CopySwapFunc *copyswap ctypedef class numpy.dtype [object PyArray_Descr]: # type PyArrayDescr_Type cdef PyTypeObject *typeobj cdef char kind cdef char type cdef char byteorder cdef char hasobject cdef int elsize cdef int alignment cdef PyArray_ArrFuncs *f ctypedef class numpy.ndarray [object PyArrayObject]: cdef dtype descr ctypedef class numpy.generic [object PyObject]: pass cdef PyTypeObject PyArrayDescr_Type cdef PyTypeObject PyGenericArrType_Type ctypedef struct PyArray_Descr: pass cdef void import_array() cdef int PyArray_RegisterDataType(dtype d) import_array() cdef class reference(generic): # members defined in .pxd """ This class represents a reference in a HDF5 table. It is designed to be a numpy user type. It does not know the file the reference is in. """ def __init__(self, dest): """ Create a reference to node dest """ cdef File file if dest is None: return file = dest._v_file H5Rcreate(&self.ref, file.file_id, dest._v_pathname, H5R_OBJECT, -1) def __str__(self): return "R%x" % self.ref def deref(self, file): """ Find and return the referenced node in file. Attention! This is a slow function, so don't call it more often than necessary. """ cdef hobj_ref_t tmp # The following loop sounds ridiculous, unfortunately, that's # the only way to retrieve the name of a referenced object. # Starting HDF5 1.8.0, one could use H5Rget_name, but it # also performs a tree traversal. It would be faster, though, # since both Python and H5Rcreate have some overhead. cdef File f f = file for node in file: H5Rcreate(&tmp, f.file_id, node._v_pathname, H5R_OBJECT, -1) if tmp == self.ref: return node raise HDF5Error("could not find referenced object") # numpy uses a strange, own way of allocating memory, not supported # directly by pyrex, thus the following two functions: # (In a bright future, this might be unnecessary) cdef object tp_new(PyTypeObject *t, PyObject *a, PyObject *b): return t.tp_alloc(t, 0) (<PyTypeObject *> reference).tp_new = tp_new (<PyTypeObject *> reference).tp_free = PyGenericArrType_Type.tp_free # Besides defining a class for the datatype, numpy needs # one dtype objects which describes the class and will be registered # with numpy. cdef PyArray_Descr stype cdef dtype type type = PyObject_Init(<PyObject *> &stype, &PyArrayDescr_Type) type.typeobj = <PyTypeObject *> reference type.kind = c'r' type.type = c'r' type.byteorder = c'=' type.hasobject = 0 type.elsize = 8 type.alignment = 8 # TODO: is that true? always? # The following functions define how to cope with a reference cdef PyArray_ArrFuncs arrfuncs cdef object getitem(hobj_ref_t *ip, ndarray ap): cdef reference ret ret = reference(None) ret.ref = ip[0] return ret arrfuncs.getitem = <PyArray_GetItemFunc *> getitem cdef int setitem(reference op, hobj_ref_t *ov, ndarray ap): ov[0] = op.ref return 0 arrfuncs.setitem = <PyArray_SetItemFunc *> setitem cdef void copyswap(hobj_ref_t *dst, hobj_ref_t *src, int swap, void *arr): dst[0] = src[0] arrfuncs.copyswap = <PyArray_CopySwapFunc *> copyswap type.f = &arrfuncs # now we can register the new datatype! PyArray_RegisterDataType(type) typeDict["r"] = reference typeDict["r8"] = reference typeDict["reference"] = reference --------------- end of reference.pyx ---------------------- ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Pytables-users mailing list Pytables-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/pytables-users