MINI MINI MANI MO
Events
======
The Component Architecture provides a way to dispatch events to event
handlers. Event handlers are registered as *subscribers*
a.k.a. *handlers*.
Before we can start we need to import ``zope.component.event`` to make
the dispatching effective:
.. doctest::
>>> import zope.component.event
Consider two event classes:
.. doctest::
>>> class Event1(object):
... pass
>>> class Event2(Event1):
... pass
Now consider two handlers for these event classes:
.. doctest::
>>> called = []
>>> import zope.component
>>> @zope.component.adapter(Event1)
... def handler1(event):
... called.append(1)
>>> @zope.component.adapter(Event2)
... def handler2(event):
... called.append(2)
We can register them with the Component Architecture:
.. doctest::
>>> zope.component.provideHandler(handler1)
>>> zope.component.provideHandler(handler2)
Now let's go through the events. We'll see that the handlers have been
called accordingly:
.. doctest::
>>> from zope.event import notify
>>> notify(Event1())
>>> called
[1]
>>> del called[:]
>>> notify(Event2())
>>> called.sort()
>>> called
[1, 2]
Object events
-------------
The ``objectEventNotify`` function is a subscriber to dispatch
ObjectEvents to interested adapters.
First create an object class:
.. doctest::
>>> class IUseless(zope.interface.Interface):
... """Useless object"""
>>> class UselessObject(object):
... """Useless object"""
... zope.interface.implements(IUseless)
Then create an event class:
.. doctest::
>>> class IObjectThrownEvent(zope.component.interfaces.IObjectEvent):
... """An object has been thrown away"""
>>> class ObjectThrownEvent(zope.component.interfaces.ObjectEvent):
... """An object has been thrown away"""
... zope.interface.implements(IObjectThrownEvent)
Create an object and an event:
.. doctest::
>>> hammer = UselessObject()
>>> event = ObjectThrownEvent(hammer)
Then notify the event to the subscribers.
Since the subscribers list is empty, nothing happens.
.. doctest::
>>> zope.component.event.objectEventNotify(event)
Now create an handler for the event:
.. doctest::
>>> events = []
>>> def record(*args): #*
... events.append(args)
>>> zope.component.provideHandler(record, [IUseless, IObjectThrownEvent])
The event is notified to the subscriber:
.. doctest::
>>> zope.component.event.objectEventNotify(event)
>>> events == [(hammer, event)]
True
Following test demonstrates how a subscriber can raise an exception
to prevent an action.
.. doctest::
>>> zope.component.provideHandler(zope.component.event.objectEventNotify)
Let's create a container:
.. doctest::
>>> class ToolBox(dict):
... def __delitem__(self, key):
... notify(ObjectThrownEvent(self[key]))
... return super(ToolBox,self).__delitem__(key)
>>> container = ToolBox()
And put the object into the container:
.. doctest::
>>> container['Red Hammer'] = hammer
Create an handler function that will raise an error when called:
.. doctest::
>>> class Veto(Exception):
... pass
>>> def callback(item, event):
... assert(item == event.object)
... raise Veto
Register the handler:
.. doctest::
>>> zope.component.provideHandler(callback, [IUseless, IObjectThrownEvent])
Then if we try to remove the object, an ObjectThrownEvent is fired:
.. doctest::
>>> del container['Red Hammer']
... # doctest: +NORMALIZE_WHITESPACE
Traceback (most recent call last):
...
raise Veto
Veto
OHA YOOOO