qubes/events.py: Fire events from parent classes too

This commit is contained in:
Wojtek Porczyk 2014-12-17 13:36:58 +01:00
parent f9658ae338
commit 6b7860995b

View File

@ -16,6 +16,10 @@ def handler(event):
To hook an event, decorate a method in your plugin class with this To hook an event, decorate a method in your plugin class with this
decorator. decorator.
It probably makes no sense to specify more than one handler for specific
event in one class, because handlers are not run concurrently and there is
no guarantee of the order of execution.
.. note:: .. note::
For hooking events from extensions, see :py:func:`qubes.ext.handler`. For hooking events from extensions, see :py:func:`qubes.ext.handler`.
@ -89,7 +93,12 @@ class Emitter(object):
def fire_event(self, event, *args, **kwargs): def fire_event(self, event, *args, **kwargs):
'''Call all handlers for an event '''Call all handlers for an event.
Handlers are called for class and all parent classess, in method
resolution order. For each class first are called bound handlers
(specified in class definition), then handlers from extensions. Aside
from above, remaining order is undefined.
:param str event: event identificator :param str event: event identificator
@ -100,11 +109,16 @@ class Emitter(object):
if not self.events_enabled: if not self.events_enabled:
return return
for handler in self.__handlers__[event]: for cls in self.__class__.__mro__:
if hasattr(handler, 'ha_bound'): # first fire bound (= our own) handlers, then handlers from extensions
# this is our (bound) method, self is implicit if not hasattr(cls, '__handlers__'):
handler(event, *args, **kwargs) continue
else: for handler in sorted(cls.__handlers__[event],
# this is from extension or hand-added, so we see method as key=(lambda handler: hasattr(handler, 'ha_bound')), reverse=True):
# unbound, therefore we need to pass self if hasattr(handler, 'ha_bound'):
handler(self, event, *args, **kwargs) # this is our (bound) method, self is implicit
handler(event, *args, **kwargs)
else:
# this is from extension or hand-added, so we see method as
# unbound, therefore we need to pass self
handler(self, event, *args, **kwargs)