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:
>>> import zope.component.event
Consider two event classes:
>>> class Event1(object): ... pass>>> class Event2(Event1): ... pass
Now consider two handlers for these event classes:
>>> 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:
>>> 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:
>>> from zope.event import notify >>> notify(Event1()) >>> called [1]>>> del called[:] >>> notify(Event2()) >>> called.sort() >>> called [1, 2]
The objectEventNotify function is a subscriber to dispatch ObjectEvents to interested adapters.
First create an object class:
>>> class IUseless(zope.interface.Interface): ... """Useless object""">>> class UselessObject(object): ... """Useless object""" ... zope.interface.implements(IUseless)
Then create an event class:
>>> 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:
>>> hammer = UselessObject()
>>> event = ObjectThrownEvent(hammer)
Then notify the event to the subscribers. Since the subscribers list is empty, nothing happens.
>>> zope.component.event.objectEventNotify(event)
Now create an handler for the event:
>>> events = [] >>> def record(*args): ... events.append(args)>>> zope.component.provideHandler(record, [IUseless, IObjectThrownEvent])
The event is notified to the subscriber:
>>> zope.component.event.objectEventNotify(event)
>>> events == [(hammer, event)]
True
Following test demonstrates how a subscriber can raise an exception to prevent an action.
>>> zope.component.provideHandler(zope.component.event.objectEventNotify)
Let’s create a container:
>>> 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:
>>> container['Red Hammer'] = hammer
Create an handler function that will raise an error when called:
>>> class Veto(Exception): ... pass>>> def callback(item, event): ... assert(item == event.object) ... raise Veto
Register the handler:
>>> zope.component.provideHandler(callback, [IUseless, IObjectThrownEvent])
Then if we try to remove the object, an ObjectThrownEvent is fired:
>>> del container['Red Hammer']
... # doctest: +NORMALIZE_WHITESPACE
...
raise Veto
Veto