[Python-ideas] Why not break cycles with one __del__?

Tim Peters tim.peters at gmail.com
Tue Sep 14 05:04:08 CEST 2010


[Nick Coghlan]
>> Alternatively, when building finalizers, build two
>> lists: one for objects with __del__ methods and one for objects that
>> are reachable from objects with __del__ methods.

[Greg Ewing]
> But since it's a cycle, isn't *everything* in the cycle
> going to be reachable from everything else?

Note that I was sloppy in saying that CPython's cyclic gc only sees
trash objects in cycles.  More accurately, it sees trash objects in
cycles, and objects (which may or may not be in cycles) reachable only
from trash objects in cycles.  For example, if objects A and B point
to each other, that's a cycle.  If A also happens to point to D, where
D has a __del__ method, and nothing else points to D, then that's a
case where D is not in a cycle, but is nevertheless trash if A and B
are trash.  And if A and B lack finalizers, then CPython's cyclic gc
will reclaim D, despite that it does have a __del__.

That pattern is exploitable too.  If, e.g., you have some resource R
that needs to be cleaned up, owned by an object A that may participate
in cycles, it's often possible to put R in a different, very simple
object with a __del__ method, and have A point to that latter object
instead.



More information about the Python-ideas mailing list