[Urwid] Bug: Signal module create backreferences

Dominic LoBue dom.lobue at gmail.com
Fri Mar 5 03:56:33 EST 2010

On Thu, Mar 4, 2010 at 1:29 PM, Dominic LoBue <dom.lobue at gmail.com> wrote:
> On Thu, Mar 4, 2010 at 12:56 PM, Dominic LoBue <dom.lobue at gmail.com> wrote:
>> On Thu, Mar 4, 2010 at 12:05 PM, Ian Ward <ian at excess.org> wrote:
>>> Dominic LoBue wrote on 2010-03-04 14:55:
>>>> While trying to figure out why my program is eating up so much ram I
>>>> discovered that objects that were supposed to be dead were still
>>>> alive. Much debugging later, I discovered that the problem was caused
>>>> by an object being kept alive by references to it by the
>>>> _urwid_signals attribute its children objects.
>>> ...
>>>> You can probably resolve this problem by using
>>>> weakref.WeakValueDictionary instead of a dict. Although personally I'd
>>>> prefer it if you switch back to having the signal registry in the
>>>> Signals class again (one big dict is smaller than thousands and
>>>> thousands of tiny ones).
>>> Hi Dominic,
>>> I would love some help in this area.  I preferred the old method too,
>>> but the way it was being done caused another leak that I couldn't find a
>>> solution to.
>>> If you can make signals work with one dictionary in the Signals class
>>> and not leak objects, please do.
>>> Ian
>>> _______________________________________________
>>> Urwid mailing list
>>> Urwid at lists.excess.org
>>> http://lists.excess.org/mailman/listinfo/urwid
>> Ian,
>> I update the signals class to use your old signals and metasignals
>> classes. You can check it out here for reference:
>> http://gist.github.com/322085
>> After upping the max_depth argument being passed to objgraph, I ran
>> the example program again and got back a massive png. The PNG is 9
>> megs, so I'll upload the .dot file instead:
>> http://upload.jkvl.com//files/2/objects.dot    To generate a png from
>> a .dot file run: dot -Tpng objects.dot -o objects.png        (Note:
>> you need graphviz to be installed)
>> I'm still going through the graph, but you may want to take a look at it too.
> Wait, I think I found it:
> <class '__main__.my_object'>: ['something'],
> in Signals._supported
> I changed _supported to a WeakKeyDictionary. This reduced the
> complexity of the graph, but the problem persists...
> Okay, the only thing left now that refers to the parent object
> "my_object" is.... the instance of its own method that is stored in
> the _connections attribute of Signals... Gotta love recursion.
> I made the stored callback a weakref.proxy object, only to get this:
> "ReferenceError: weakly-referenced object no longer exists"


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:

Dominic LoBue

More information about the Urwid mailing list