[Python-Dev] Re: weakref gc semantics

Tim Peters tim.peters at gmail.com
Thu Nov 4 20:32:51 CET 2004


[Neil Schemenauer]
> I like this idea [patch-callback] best.  I don't see why it should be hard to
> explain.  Instead of saying:
>
>    If you want the weakref callback to be invoked, ensure the
>    WEAKREF outlives the referent.
>
> we say:
>
>    If you want the weakref callback to be invoked, ensure the
>    CALLBACK outlives the referent.

The former is accurate independent of whether we're talking about
cyclic trash now, but that latter would not be.  For example,

def callback(ignore):
    print 'hi'

class C:
    pass

c = C()
w = weakref.ref(c, callback)
w = None
c = None

The callback outlives c, but the callback doesn't get invoked, because
w didn't outlive c.  The callback does get invoked if the order of the
last two lines is swapped.  It's easy to explain this in terms of
which of {c, w} goes away first, but not in terms of callback's
lifetime.

> I think there may be one small problem though.  Callbacks get passed
> the weakref object.  Doesn't that break the rule that trash should
> not be exposed to Python code while the collection is taking place?

That's why I'm not touching anything here again for 2.4 <wink>.  For
builtin weakrefs to trash, it doesn't matter -- they get cleared
before gc invokes any callbacks, so the worst a callback on a
builtin-weakref-to-trash-object could do with its argument is
resurrect a weakref than returns None if you call it.  BFD.

But I think we could concoct tests where instances of a weakref
subclass did arbitrary damage in callbacks, via attributes bound to
trash objects.  The current "invoke the callback iff the weakref is
reachable" avoids getting in trouble there, and I had weakref
subclasses in the back of my mind when "settling" for that.  We should
write some nasty tests of weakref subclasses with callbacks
interacting with gc -- there aren't any now.


More information about the Python-Dev mailing list