[Urwid] Bug: Signal module create backreferences

Ian Ward ian at excess.org
Sat Mar 27 16:39:10 EDT 2010

Dominic LoBue wrote on 2010-03-05 03:56:
> Ian,
> I have a working implementation. By no means is it elegant, but it works.
> Basically instead of holding onto the specific method that is to be
> called when a signal is recieved, we instead hold onto a tuple of
> (ref(parentwithmethod), 'methodname'). When the signal is activated,
> we use getattr to get an instance of the method we want and then run
> that method.
> Working examples can be found here:
> http://gist.github.com/322577
> http://gist.github.com/322576

I just want to make sure I have a good understanding of what is
happening with these references.  The old way of tracking signals was a
single WeakKeyDictionary:

signals._connections = WeakKeyDictionary({
    object_that_sends_signal : {
        signal_name : [
            (callback_function, user_argument)]}})

And in common use the callback_function is a bound method on the object
that receives the signal.

This receiving object may be the last thing holding a reference to the
sending object, however when the receiving object is removed the bound
method keeps it alive, in turn keeping the sending object alive and
circular references in _connections are never removed.

The same thing happens with the current code, except _connections is now
in the sending object and nothing points to the dead objects, so I
assume they would eventually get picked up by the garbage collector.

(please correct me if I'm wrong)

One problem with your solution is that it only helps if the
callback_function is a bound method.  What if it's a normal function
that happened to pull in a reference to the sending object from its
enclosing scope?

I'll need to dig in to this a little more, I think..



More information about the Urwid mailing list