[Python-Dev] Re: [PythonLabs] Re: [Python-checkins]python/dist/src/Modules gcmodule.c,,

Tim Peters tim.one@comcast.net
Sat, 05 Apr 2003 19:05:21 -0500

[Jeremy Hylton]
> We've got the first version of boom nailed, but we've got the same
> problem in handle_finalizers().  The version of boom below doesn't blow
> up until the second time the has_finalizer() is called.

It isn't really necessary to call has_finalizer() a second time, and I'll
check in changes so that it doesn't anymore (assuming the test suite
passes -- it's running as I type this).

> I don't understand the logic in handle_finalizers(), though.  If the
> objects are all in the finalizers list, why do we call has_finalizer() a
> second time?  Shouldn't everything has a finalizer at that point?

I tried to explain that last night.  The essence of the changes I have
pending is to make move_finalizer_reachable() move the tentatively
unreachable objects reachable only from finalizers into a new & distinct
list, reachable_from_finalizers.  After that, everything in finalizers has a
finalizer and nothing in reachable_from_finalizers does, so we don't have to
call has_finalizer() again. Before, finalizers contained everything in both
(finalizers and reachable_from_finalizers) lists, so another has_finalizer()
call on each object was needed to distinguish the two kinds (has a
finalizer, doesn't have a finalizer) of objects again.

> import gc
> class C:
>     def __init__(self):
>         self.x = 0
>     def delete(self):
>         print "never called"
>     def __getattr__(self, attr):
>         self.x += 1
>         print self.x
>         if self.x > 1:
>             del self.attr
>         else:
>             return self.delete
>         raise AttributeError
> a = C()
> b = C()
> a.attr = b
> b.attr = a
> del a, b
> print gc.collect()

I also added a non-printing variant of this to test_gc.  In the new world,
the "del self.attr" bits never get called, so this is just a vanilla trash
cycle now.