Thanks  that's pretty close to what I'm doing now.  I'm a bit new to 
writing Python extension classes and I'm just
working out the logic of the reference counting mechanism.

It turns out that the tricky part is overriding the allocation and 
deallocation of the python objects associated with my extension class,
as well as the extension class structure itself.

The logical place to try to capture a cython class that's being 
destroyed is in __dealloc__().  However as I mentioned earlier,
once you are actually in __dealloc__() there is no way to save the 
allocated data structure associated with self that I could see.

I have no idea when __del__() is supposed to be called.  I put a print 
statement in that attribute and it never was called.

Thus even if I had the code as you've written it,  it would fail if I 
had attempted to save the object by using a Py_INCREF.  Once you're in 
__dealloc__()  self will be destroyed no matter what the ref count is,  
as far as I can tell (cython 0.11.2 behavior).  So my current strategy 
is to create a new container class for the hash function that simply 
holds all the attributes of self.  I'll have to test if I need a 
Py_INCREF for any attributes that are python objects contained in self. 
   It's not quite as nice since there will be an extra python/cython 
allocation of the hash container class.

Earlier I had thought the python objects contained in self were also 
being automatically destroyed if their refcounts were 0, but such 
behavior would be a bug I think.

If there was a way to intercept a garbage collect prior to __dealloc__() 
or to override the default behavior of destroying self,  then I could 
avoid the extra allocation of the hash container.  I'll be doing some 
tests soon to see how much it costs me.

-Matt


On 2:59 PM, Sturla Molden wrote:
>    
>> I was wrong.  A buffer of the type
>> cdef object[int] myhash
>> can only be declared locally inside some function or method.
>>      
>
> Then write an extension class that wraps the buffer, and store one on
> module scope. Something like this (not tested):
>
>
> DEF BUF_SIZE = 32
>
> import myclass # your extension class
>
> from python cimport PyObject, Py_INCREF, Py_DECREF
>
> cdef class bufferwrapper:
>
>      cdef PyObject *buffer[BUF_SIZE]
>
>      def __cinit__(bufferwrapper self):
>          cdef int n
>          for n in range(BUF_SIZE):
>              self.buffer[n] = NULL
>
>      def __init__(bufferwrapper self):
>          cdef int n
>          cdef object tmp
>          for n in range(BUF_SIZE):
>              tmp = myclass.myclass()
>              Py_INCREF(tmp)
>              self.buffer[n] =<PyObject*>  tmp
>
>      def __dealloc__(bufferwrapper self):
>          cdef int n
>          for n in range(BUF_SIZE):
>              if self.buffer[n] != NULL:
>                  Py_DECREF(<object>  self.buffer[n])
>
> cdef bufferwrapper _buffer = bufferwrapper()
>
> def foobar(int hashvalue):
>      cdef object obj
>      obj =<object>  _buffer.buffer[hashvalue]
>
>
>
> Regards,
> Sturla Molden
>
>
>
>
>
>    
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to