[Pyrex] cdef'd classes initialization

Greg Ewing greg.ewing at canterbury.ac.nz
Fri Aug 11 01:47:46 UTC 2006


Daniele Varrazzo wrote:

> I stumbled against the Pyrex __new__ peculiar behavior: all the 
> superclasses' __new__ get called and no communication is available in 
> the calls chain.

I realise that this is an awkward restriction at times,
and I'm thinking about ways of removing it, but it's
tricky.

> For example, in my library each subclass of a base class must allocate 
> some heap space: different subclasses require different amount of space.

You could have the base class initially malloc() what
it needs, and subclasses realloc() it as necessary.

> Which can be read "In __new__ method, virtual methods are not virtual",
> just as in C++ constructors.

That behaviour mostly fell out of the implementation.
Setting the vtable pointer is done by the tp_new code
that Pyrex generates, just before calling the object's
__new__ method. This means that it's initially set to
the vtable of the root class, its __new__ is executed,
then it's re-set to the vtable of the next class down
the chain, its __new__ is executed, etc.

However, this seemed to be not-unreasonable behaviour,
since calling the methods of a given type before the
object has been fully initialised as an object of that
type could lead to surprises. So I didn't worry about
trying to do it any differently.

However, one of the tricky things I mentioned in the
first paragraph concerns where and how to set the
vtable pointer, so this might change one day.

> would it be
> possible to hide CRoot from the module dict?

You can do something like this:

   # foo.pyx

   cdef class C:
     ...
	
   import foo
   del foo.C

However, keep in mind that Python code can always
get at a class given an instance of that class,
so at best this reduces the chance of accidental
misuse.

--
Greg



More information about the Pyrex mailing list