Reputation: 1108
In the documentation it is written that "Any C data that you explicitly allocated (e.g., via malloc) in your _cinit_() method should be freed in your _dealloc_() method."
This is not my case. I have following extension class:
cdef class SomeClass:
cdef dict data
cdef void * u_data
def __init__(self, data_len):
self.data = {'columns': []}
if data_len > 0:
self.data.update({'data': deque(maxlen=data_len)})
else:
self.data.update({'data': []})
self.u_data = <void *>self.data
@property
def data(self):
return self.data
@data.setter
def data(self, new_val: dict):
self.data = new_val
Some C function has an access to this class and it appends some data to SomeClass().data dict. What should I write in __dealloc__
, when I want to delete the instance of the SomeClass()?
Maybe something like:
def __dealloc__(self):
self.data = None
free(self.u_data)
Or isn't there any need to dealloc anything at all?
Upvotes: 3
Views: 1691
Reputation: 30889
No you don't need to and no you shouldn't. From the documentation
You need to be careful what you do in a
__dealloc__()
method. By the time your__dealloc__()
method is called, the object may already have been partially destroyed and may not be in a valid state as far as Python is concerned, so you should avoid invoking any Python operations which might touch the object. In particular, don’t call any other methods of the object or do anything which might cause the object to be resurrected. It’s best if you stick to just deallocating C data.You don’t need to worry about deallocating Python attributes of your object, because that will be done for you by Cython after your
__dealloc__()
method returns.
You can confirm this by inspecting the C code (you need to look at the full code, not just the annotated HTML). There's an autogenerated function __pyx_tp_dealloc_9someclass_SomeClass
(name may vary slightly depending on what you called your module) does a range of things including:
__pyx_pw_9someclass_9SomeClass_3__dealloc__(o);
/* some other code */
Py_CLEAR(p->data);
where the function __pyx_pw_9someclass_9SomeClass_3__dealloc__
is (a wrapper for) your user-defined __dealloc__
. Py_CLEAR
will ensure that data
is appropriately reference-counted then set to NULL
.
It's a little hard to follow because it all goes through several layers of wrappers, but you can confirm that it does what the documentation says.
Upvotes: 5