weakref pitfall

Paul Hankin paul.hankin at gmail.com
Sat Oct 20 10:21:08 EDT 2007


On Oct 20, 2:47 pm, Odalrick <odalr... at hotmail.com> wrote:
> I'm trying to write a simple game and decided I need an eventmanager.
>
> <code>
> import weakref
> from collections import defaultdict
>
> class _EventManager( object ):
>     def __init__( self ):
>         self._handled_events =
> defaultdict( weakref.WeakKeyDictionary )
>
>     def register( self, handler, event_type, filter=None ):
>         self._handled_events[event_type][handler] = filter
>
>     def deregister( self, handler, event_type ):
>         self._handled_events[event_type].pop( handler, None  )
>
>     def handle_event( self, event ):
>         event_type = event.type
>         for handler, filter in
> self._handled_events[event_type].items():
>             if filter == None or filter(event):
>                 handler( event )
>
> eventmanager = _EventManager()
>
> __all__ = [ eventmanager ]
> </code>
>
> Fairly simple, yet there was some strange bug that prevented my game
> from exiting.
>
> I think what happened was that when __init__ ends, self goes out of
> scope, and by extension so does self.handle_quit, Now there are no
> more refeences to self.handle_quit, because weakrefs don't count, and
> the event gets automatically dropped from my eventmanager. I thought
> that wouldn't happen because handle_quit is part of the class and
> instance MainGame.
>
> Am I right in my guess? If so, how should I adress this bug? If not,
> what is the bug?

The next stage in debugging is to think of a test that will prove your
guess right or wrong. I'd remove weakrefs from your event manager and
see if your code starts working.

I'd suggest you're a bit confused about your event manager's API: you
have register/deregister methods and are also using weakrefs to
provide auto-deregistering. I don't know your code, but this looks
like a mistake to me - can you justify (to yourself) that you need
both ways?

--
Paul Hankin




More information about the Python-list mailing list