Notice the behaviour has not changed at all -- we just have made a local reference to keep the handler alive inside a weakref dictionary inside the TornadoEventLoop. No other event loops are affected by this change, no need to change anything.

I had to use weakrefs because:
 +        Notice, since Tornado has no concept of idle callbacks we
 +        monkey patch ioloop._impl.poll() function to be able to detect
 +        potential idle periods.
But because the existing code does not keep a local temporary reference to self.entering_idle when calling self.event_loop.enter_idle() the parameter gets garbage collected.

The problem is urwid expects certain functionality from an event loop to be wrapped (i.e. idle callbacks) which Tornado does not support. This is why I had to simulate it with a patched poll object and a weak handler registry.

We can avoid making this change by not using WeakValueDictionary but that may potentially introduce a leak. Though I really think this change is completely harmless and more so beneficial.

Could you expand on the idea of using signals here?