[Python-Dev] __del__ is not called after creating a new reference

Oleg Nesterov oleg at redhat.com
Sun Apr 2 13:20:14 EDT 2017


On 04/02, Armin Rigo wrote:
>
> Hi all,
>
> On 20 March 2017 at 22:28, Nathaniel Smith <njs at pobox.com> wrote:
> > Modern CPython, and all extant versions of PyPy and Jython, guarantee that
> > __del__ is called at most once.
>
> Just a note, if someone actually depends on this: it is not true in
> all cases.  For example, in CPython 3.5.3:
>
> >>> class X:
> ...   __slots__=()        #   <= note this!
> ...   def __del__(self):
> ...     print("DEL")
> ...     global resurrect
> ...     resurrect = self
> ...
> >>> print(X())
> <__main__.X object at 0x7f5d1ad600d0>
> DEL
> >>> resurrect=None
> DEL

Objects/typeobject.c:type_new()

    /* Enable GC unless this class is not adding new instance variables and
       the base class did not use GC. */
    if ((base->tp_flags & Py_TPFLAGS_HAVE_GC) ||
        type->tp_basicsize > base->tp_basicsize)
        type->tp_flags |= Py_TPFLAGS_HAVE_GC;

That is. "type->tp_basicsize > base->tp_basicsize" is false if empty __slots__,
so we do not set HAVE_GC.

And PyObject_CallFinalizer() doesn't set FINALIZED if PyType_IS_GC(tp) == F.

Oleg.



More information about the Python-Dev mailing list