[Pyrex] cdef'd classes initialization

Daniele Varrazzo daniele.varrazzo at gmail.com
Tue Aug 8 16:33:22 UTC 2006


Hello,

i wrote some Pyrex classes to wrap C structures. Usually such classes
are responsible for the wrapped structure, and properly allocate them on
the heap and initialize on __init__ and free on __dealloc__. This is the
normal behaviour for all the instances directly created by a Python program.

Inside Pyrex, i don't always want such behavior. For example i have some
composite structures: the component is accessed from the composing
structure using a property. When the property __get__ is invoked, i
create from Pyrex a new instance to wrap the component structure. But
this instance doesn't own the wrapped structure: on __dealloc__ it must
not free() anything.

I don't like the way i implemented this mechanism: any such object has a
constructor:

     def __init__(self, viewer=False):
         if not viewer:
             # allocation and initialization
         else:
             # other required things

but this constructor _must_ be called with default viewer=False from
Python: the case viewer=True is reserved for internal usage.

Furthermore viewers initialization is not complete: in the viewer case,
the structure pointer can't be set through a Python call (it's a void
*), so a property getter usually involves an idiom such as:

     cdef MeasFileHeader rv
     rv = MeasFileHeader(viewer=1)
     rv.setStruct(&md.measFileHeader)
     return rv

"More furthermore", this mechanism involves a Python call from C, with
the related Python call overhead (a dict and a tuple must be created, etc.)

So the question: is it possible to initialize a cdef'd class without
using the Python def'd __init__ method? If so i could create a factory
function (or a protected init method) implementing the "# other required
things" case above. I'd like to do:

     def __init__(self):              # to be called by Python
         self.init_owner()

     cdef init_owner(self):           # to be called by Pyrex
         # allocation and initialization

     cdef init_viewer(self, void *s): # for Pyrex getters
         # other required things
         self.setStruct(s)

Can an instance be created by Pyrex without the __init__ call but with
an init_owner() or init_viewer() call instead? Or also without any call
at all? - i'd write proper (Pyrex) factory functions to be invoked to
create a new object instance.

Daniele





More information about the Pyrex mailing list