[Python-Dev] __traceback__ and reference cycles
tim.peters at gmail.com
Tue Aug 9 04:37:56 CEST 2005
>> If P3K retains them [__del__]-- or maybe even before --we should
>> consider taking "the Java dodge" on this one. That is, decree that
>> henceforth a __del__ method will get invoked by magic at most
>> once on any given object O, no matter how often O is resurrected.
[Phillip J. Eby]
> How does that help?
You have to dig into Armin's example (or read his explanation): every
time __del__ is called on one of his X objects, it creates a cycle by
binding sys.exec_info() to the local vrbl `e_tb`. `self` is
reachable from that cycle, so self's refcount does not fall to 0 when
__del__ returns. The object is resurrected. When cyclic gc next
runs, it determines that the cycle is trash, and runs around
decref'ing the objects in the cycle. That eventually makes the
refcount on the X object fall to 0 again too, but then its __del__
method also runs again, and creates an isomorphic cycle, resurrecting
`self` again. Etc.
Armin didn't point this out explicitly, but it's important to realize
that gc.garbage remains empty the entire time you let his program run.
The object with the __del__ method isn't _in_ a cycle here, it's
hanging _off_ a cycle, which __del__ keeps recreating. Cyclic gc
isn't inhibited by a __del__ on an object hanging off a trash cycle
(but not in a trash cycle itself), but in this case it's ineffective
If __del__ were invoked only the first time cyclic gc ran, the
original cycle would go away during the next cyclic gc run, and a new
cycle would not take its place.
> Doesn't it mean that we'll have to have some way of keeping track of
> which items' __del__ methods were called?
Yes, by hook or by crook; and yup too, that may be unattractive.
More information about the Python-Dev