I have the following C++ class :
.H
class ALabSet: public LabSet {
public:
PyObject *m_obj;
ALabSet(PyObject *obj);
virtual ~ALabSet();
del a_set
removes a reference to the object (the local variable). There's still another reference, in the C++ object. This is known as a reference cycle. The cycle GC could collect this after a while. However, there is no guarantee when (or even if) this happens, so you should not rely on it1.
For example, reference cycles containing pure Python objects with a __del__ special method are documented to not be freed at all:
Changed in version 3.4: Following PEP 442, objects with a
__del__()
method don’t end up ingc.garbage
anymore.
I don't know whether Cython's implementation of __dealloc__ triggers this behavior, but as outlined before, destruction isn't deterministic anyway. If you want to free some resource (e.g. a block of memory that isn't a Python object, a file, a connection, a lock, etc.) you should expose an explicit way of doing so manually (cf. the close
methods of various objects). Context managers can simplify client code doing this.
Disclaimer: Almost all of this is CPython-specific.
1 Some people prefer thinking of GC as an abstraction that simulates availability of infinite memory, rather than something that destroys unreachable objects. With this approach, it becomes quite obvious that destruction is not deterministic and not even guaranteed.