[Pyrex] Cannot cdef __init__?

Andrew Bennetts andrew-pyrex at puzzling.org
Mon Jan 19 12:10:40 CET 2004


On Sun, Jan 18, 2004 at 05:30:03PM -0800, Paul Prescod wrote:
> How about this variant:
> 
> cdef extern from "foo.h":
>         cdef struct pair:
>                 int x
>         cdef int libblah_init_pair(pair **p, int y)
>         int libblah_decref(pair *p)
>         int libblah_incref(pair *p)
> 
> cdef class Pair:
>         cdef pair *p
>         def __init__(self, x, y):
>                 rc = libblah_init_pair(&self.p, y)

Ok, so basically the key here is to call the library's init function inside
my wrapper class's __init__.

What if there is more than one function that creates a struct in the
library? (Sorry; this is yet another requirement I forgot to mention
earlier!  I'm not making this easy for you.)

E.g. say there was a function:

    pair * libblah_pair_add(pair *a, pair *b);

in this library as well?

I can see that with sufficient effort I can use workarounds to make this
sort of thing work, but I still find myself thinking that I should simply be
able to do:

cdef class Pair:
    cdef pair *p
    cdef __init__(self, pair *p):
        if p == NULL:
            raise TypeError, "p must not be NULL"
        self.p = p
        libblah_ref(p)

    # ...

    def __del__(self):
        libblah_deref(self.p)

Which is of course where I started this thread :)

I realise that this would make the type uncallable from Python, but that's
hardly without precedent:

>>> None.__class__()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: cannot create 'NoneType' instances

If I wrote a patch to allow Pyrex to support this, would it be likely to be
accepted?  I'm surprised that no-one else has done this already (which makes
me wonder if I'm still somehow just not "getting it").

Thanks for all your help,

-Andrew.





More information about the Pyrex mailing list