
Hello, I already tried to ask on python-list, see https://mail.python.org/pipermail/python-list/2017-March/720037.html but it seems that this list is not for technical questions. Let me resend my question to python-dev. Please tell me if I should not spam this list with newbiesh questions, and thanks in advance. --------------------------------------------------------------------------- I started to learn python a few days ago and I am trying to understand what __del__() actually does. https://docs.python.org/3/reference/datamodel.html says: object.__del__(self) ... Note that it is possible (though not recommended!) for the __del__() method to postpone destruction of the instance by creating a new reference to it. It may then be called at a later time when this new reference is deleted. However, this trivial test-case class C: def __del__(self): print("DEL") global X X = self C() print(X) X = 0 print(X) shows that __del__ is called only once, it is not called again after "X = 0": DEL <__main__.C object at 0x7f067695f4a8> 0 (Just in case, I verified later that this object actually goes away and its memory is freed, so the problem is not that it still has a reference). I've cloned https://github.com/python/cpython.git and everything looks clear at first glance (but let me repeat that I am very new to python): PyObject_CallFinalizerFromDealloc() calls PyObject_CallFinalizer() which finally calls "__del__" method in slot_tp_finalize(), then it notices that "X = self" creates the new reference and does: /* tp_finalize resurrected it! Make it look like the original Py_DECREF * never happened. */ refcnt = self->ob_refcnt; _Py_NewReference(self); self->ob_refcnt = refcnt; However, PyObject_CallFinalizer() also does _PyGC_SET_FINALIZED(self, 1) and that is why __del__ is not called again after "X = 0": /* tp_finalize should only be called once. */ if (PyType_IS_GC(tp) && _PyGC_FINALIZED(self)) return; The comment and the code are very explicit, so this does nt look like a bug in cpython. Probably the docs should be fixed? Or this code is actually wrong? The test-case works as documented if I remove _PyGC_SET_FINALIZED() in PyObject_CallFinalizer() or add another _PyGC_SET_FINALIZED(self, 0) into PyObject_CallFinalizerFromDealloc() after _Py_NewReference(self), but yes, yes, I understand that this is not correct and won't really help. Oleg.