From 8e3ada5c9248119eed613340b124890ffb61ab75 Mon Sep 17 00:00:00 2001 From: Robin Narsingh Ranabhat Date: Sat, 23 Aug 2025 01:04:55 +0545 Subject: [PATCH] gh-137740: Clarify `__del__` invocation mechanism in reference counting (GH-137741) (cherry picked from commit 90b932e65080008dfd974b2e03c3068dbb72b95d) Co-authored-by: Robin Narsingh Ranabhat Co-authored-by: Kumar Aditya --- Doc/extending/extending.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index fd63495674651b..0c3763b9243e98 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -1059,7 +1059,14 @@ references to all its items, so when item 1 is replaced, it has to dispose of the original item 1. Now let's suppose the original item 1 was an instance of a user-defined class, and let's further suppose that the class defined a :meth:`!__del__` method. If this class instance has a reference count of 1, -disposing of it will call its :meth:`!__del__` method. +disposing of it will call its :meth:`!__del__` method. Internally, +:c:func:`PyList_SetItem` calls :c:func:`Py_DECREF` on the replaced item, +which invokes replaced item's corresponding +:c:member:`~PyTypeObject.tp_dealloc` function. During +deallocation, :c:member:`~PyTypeObject.tp_dealloc` calls +:c:member:`~PyTypeObject.tp_finalize`, which is mapped to the +:meth:`!__del__` method for class instances (see :pep:`442`). This entire +sequence happens synchronously within the :c:func:`PyList_SetItem` call. Since it is written in Python, the :meth:`!__del__` method can execute arbitrary Python code. Could it perhaps do something to invalidate the reference to