[Python-Dev] Making weakref callbacks safe in cyclic gc
nas-python at python.ca
Mon Nov 17 16:46:45 EST 2003
On Mon, Nov 17, 2003 at 02:20:30PM -0500, Tim Peters wrote:
> When a weakref goes away, its callback (if any) goes away too,
> unexecuted, cyclic gc or not.
I did not know that.
> It's the one-shot business that (I think) makes them easier to
> live with, in conjunction with that a callback vanishes if the
> weakref holding it goes away. A __del__ method never goes away.
> While a callback *can* install new callbacks, all over the place,
> I don't expect that real code does that. For code that doesn't,
> gc can make good progress.
That sounds pragmatic and Pythonic.
> Jim empathically doesn't want to poll gc.garbage looking for
> weakrefs that appear in cycles. Maybe "tough luck" is the best
> response we can come up with to that, but cycles are getting very
> easy to create in Python by accident, so I don't really want to
> settle for that.
Agreed. It sucks to have to make things a lot more inconvenient
just because it's theoretically possible for people to make the
system behave badly.
> Another scheme is to just run all the weakref callbacks associated
> with trash cycles, without tp_clear'ing anything first. Then run
> gc again to figure out what's still trash, and repeat until no
> more weakref callbacks in trash cycles exist.
Repeatedly running the GC sounds like trouble to me. I think it
would be better to move everything reachable from them into the
youngest generation, finish the GC pass and then run them. I
haven't been thinking about this as hard as you have though, so
perhaps I'm missing some subtlety.
I have to wonder if anyone would care if __del__ methods were
one-shot as well. As a user, I would rather have one-shot __del__
methods and not have to deal with gc.garbage. It would be nice if
we could treat both kinds of finalizers consistently. Unfortunately
I can't think of a way of noting that the __del__ method was already
I suppose if __del__ method continued to work the way they do,
people could just use weakref callbacks to do finalization.
More information about the Python-Dev