[pypy-issue] [issue1687] weakref and __del__ (object disappears)

Armin Rigo tracker at bugs.pypy.org
Thu Feb 13 15:49:00 CET 2014

Armin Rigo <armin.rigo at gmail.com> added the comment:

Ok, figured out why we get this behavior.  I think the issue was introduced when
we made the Garbage Collector incremental.  Here it goes:

1. We have an object x that has both a finalizer (a __del__ method) and a
weakref to it.

2. At the end of the MARKING state of collection, we figure out that x has no
more references, so we enqueue "call the finalizer" and resurrect x so that it
is still usable in the finalizer. As a result, x is resurrected, and we do NOT
free the link from the weakref to x yet.

3. Now, at a _later_ step of the same collection, we actually call the
RPython-level finalizer, which invalidates the weakref as the first step.

But the Python program might have done anything between steps 2 and 3, like
fetching a strong reference to x via the weakref.  So at step 3 we will
incorrectly invalidate a weakref that might have strong references around.  We
will also incorrectly call the __del__() method on the object even with strong
references around.

Note that we need to be careful when fixing this, because CPython rules that
weakrefs are cleared before the __del__() method is called --- even though of
course there is still a reference to the object, as we're going to call a method
on it.  Likely, the fix should be along the lines of: in the step 2 above, we
should still free the links from the weakref to x, IF we schedule x's finalizer
to be called; but we should NOT free the links from other weakrefs to other
objects IF we don't schedule their finalizers to be called.

nosy: +arigo

PyPy bug tracker <tracker at bugs.pypy.org>

More information about the pypy-issue mailing list