![](https://secure.gravatar.com/avatar/fa0f7819f1825f596b384c19aa7dcf33.jpg?s=120&d=mm&r=g)
INADA Naoki <songofacandy@gmail.com> added the comment: I think I can describe what two function does/for. But I'm not good English writer. Would you write document instead? --- "Finalizer" is __del__ in Python and tp_finalize in C. Calling finalizer requires some tricks, including avoiding call twice. That is what PyObject_CallFinalizer() does. Use it instead of call `type->tp_finalize(obj)` directly. But finalizer is called from destructor (tp_dealloc) usually, and calling finalizer from destructor need more hack (e.g. temporary increment refcount). This is what PyObject_CallFinalizerFromDealloc does. Generally speaking, this API is used only when you want to use both of custom tp_dealloc and tp_finalize. This is very rare because you can write cleanup code in tp_dealloc and skip using tp_finalize. When you need really need both of tp_dealloc and tp_finalize, note that: * Finalizer may resurrect the object. * When the type is subclassed from Python, tp_finalize is called automatically. You must not call PyObject_CallFinalizerFromDealloc then. This is tp_dealloc of Future object in asyncio. This object uses both of tp_dealloc and tp_finalize for compatibility with Future object implemented in pure Python. This covers many edge cases of tp_dealloc. ``` static void FutureObj_dealloc(PyObject *self) { FutureObj *fut = (FutureObj *)self; if (Future_CheckExact(fut)) { /* When fut is subclass of Future, finalizer is called from * subtype_dealloc. */ if (PyObject_CallFinalizerFromDealloc(self) < 0) { // resurrected. return; } } // Weakref callback and finalizer of other objects may start GC. // So you need to untrack this object from GC before calling PyObject_ClearWeakRefs() // or any Py_DECREF()s // Otherwise, GC will cause segfault because refcount of this object is 0. PyObject_GC_UnTrack(self); // Handle weakrefs if (fut->fut_weakreflist != NULL) { PyObject_ClearWeakRefs(self); } // Reuse tp_clear() for clearing all members. (void)FutureObj_clear(fut); // Free this object at last. Py_TYPE(fut)->tp_free(fut); } ``` ---------- nosy: +inada.naoki _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue33909> _______________________________________