[Zope3-checkins]
SVN: Zope3/branches/jim-adapter/src/zope/component/
Added a dispatcher that dispatches to registered components.
Jim Fulton
jim at zope.com
Tue Apr 18 19:56:38 EDT 2006
Log message for revision 67111:
Added a dispatcher that dispatches to registered components.
Also refactoried the registration objects and interfaces to make the
different registration types more distinct.
Changed:
U Zope3/branches/jim-adapter/src/zope/component/interfaces.py
U Zope3/branches/jim-adapter/src/zope/component/registry.py
U Zope3/branches/jim-adapter/src/zope/component/registry.txt
-=-
Modified: Zope3/branches/jim-adapter/src/zope/component/interfaces.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/component/interfaces.py 2006-04-18 23:56:35 UTC (rev 67110)
+++ Zope3/branches/jim-adapter/src/zope/component/interfaces.py 2006-04-18 23:56:37 UTC (rev 67111)
@@ -166,8 +166,8 @@
named adapter methods with an empty string for a name.
"""
- def queryAdapter(object, interface=interface.Interface, name=u'', default=None,
- context=None):
+ def queryAdapter(object, interface=interface.Interface, name=u'',
+ default=None, context=None):
"""Look for a named adapter to an interface for an object
Returns an adapter that can adapt object to interface. If a matching
@@ -514,7 +514,7 @@
component = interface.Attribute("The object registered")
provided = interface.Attribute("The interface provided by the component")
-class IAdapterRegistration(IRegistration):
+class _IBaseAdapterRegistration(IRegistration):
"""Information about the registration of an adapter
"""
@@ -532,7 +532,11 @@
This interface is implemented by the factory
""")
-class ISubscriptionAdapterRegistration(IAdapterRegistration):
+class IAdapterRegistration(_IBaseAdapterRegistration):
+ """Information about the registration of an adapter
+ """
+
+class ISubscriptionAdapterRegistration(_IBaseAdapterRegistration):
"""Information about the registration of a subscription adapter
"""
Modified: Zope3/branches/jim-adapter/src/zope/component/registry.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/component/registry.py 2006-04-18 23:56:35 UTC (rev 67110)
+++ Zope3/branches/jim-adapter/src/zope/component/registry.py 2006-04-18 23:56:37 UTC (rev 67111)
@@ -17,8 +17,9 @@
"""
import types
+import zope.deprecation
import zope.interface.adapter
-from zope import interface
+from zope import component, interface
from zope.component import interfaces
import zope.interface.interfaces
import zope.event
@@ -68,6 +69,10 @@
if provided is None:
provided = _getUtilityProvided(component)
+ if (self._utility_registrations.get((provided, name))
+ == (component, info)):
+ # already registered
+ return
subscribed = [
1
@@ -386,6 +391,8 @@
class UtilityRegistration(object):
+ interface.implements(interfaces.IUtilityRegistration)
+
def __init__(self, registry, provided, name, component, doc):
(self.registry, self.provided, self.name, self.component, self.info
) = registry, provided, name, component, doc
@@ -403,6 +410,8 @@
class AdapterRegistration(object):
+ interface.implements(interfaces.IAdapterRegistration)
+
def __init__(self, registry, required, provided, name, component, doc):
(self.registry, self.required, self.provided, self.name,
self.factory, self.info
@@ -428,10 +437,13 @@
return self.factory
class SubscriptionRegistration(AdapterRegistration):
- pass
+ interface.implementsOnly(interfaces.ISubscriptionAdapterRegistration)
+
class HandlerRegistration(AdapterRegistration):
+ interface.implementsOnly(interfaces.IHandlerRegistration)
+
def __init__(self, registry, required, name, handler, doc):
(self.registry, self.required, self.name, self.handler, self.info
) = registry, required, name, handler, doc
@@ -450,4 +462,26 @@
self.name,
getattr(self.factory, '__name__', `self.factory`), self.info,
)
+
+
+ at component.adapter(interfaces.IUtilityRegistration,
+ interfaces.IRegistrationEvent)
+def dispatchUtilityRegistrationEvent(registration, event):
+ component.handle(registration.component, event)
+
+ at component.adapter(interfaces.IAdapterRegistration,
+ interfaces.IRegistrationEvent)
+def dispatchAdapterRegistrationEvent(registration, event):
+ component.handle(registration.factory, event)
+
+ at component.adapter(interfaces.ISubscriptionAdapterRegistration,
+ interfaces.IRegistrationEvent)
+def dispatchSubscriptionAdapterRegistrationEvent(registration, event):
+ component.handle(registration.factory, event)
+
+ at component.adapter(interfaces.IHandlerRegistration,
+ interfaces.IRegistrationEvent)
+def dispatchHandlerRegistrationEvent(registration, event):
+ component.handle(registration.handler, event)
+
Modified: Zope3/branches/jim-adapter/src/zope/component/registry.txt
===================================================================
--- Zope3/branches/jim-adapter/src/zope/component/registry.txt 2006-04-18 23:56:35 UTC (rev 67110)
+++ Zope3/branches/jim-adapter/src/zope/component/registry.txt 2006-04-18 23:56:37 UTC (rev 67111)
@@ -16,9 +16,9 @@
implementation of zope.component.interfaces.IComponents that provides
these features.
- >>> from zope.component.registry import Components
+ >>> from zope.component import registry
>>> from zope.component import tests
- >>> components = Components('comps')
+ >>> components = registry.Components('comps')
As components atr registered, events are generated. Let's register
an event subscriber, so we can see the events generated:
@@ -854,11 +854,11 @@
Component-management objects can extend other component-management
objects.
- >>> c1 = Components('1')
+ >>> c1 = registry.Components('1')
>>> c1.__bases__
()
- >>> c2 = Components('2', (c1, ))
+ >>> c2 = registry.Components('2', (c1, ))
>>> c2.__bases__ == (c1, )
True
@@ -879,8 +879,8 @@
We can use multiple inheritence:
- >>> c3 = Components('3', (c1, ))
- >>> c4 = Components('4', (c2, c3))
+ >>> c3 = registry.Components('3', (c1, ))
+ >>> c4 = registry.Components('4', (c2, c3))
>>> c4.queryUtility(tests.I1)
U1(2)
@@ -926,3 +926,130 @@
handle3 U1(1)
handle (U1(1),)
handle4 U1(1)
+
+Redispatch of registration events
+---------------------------------
+
+Some handlers are available that, if registered, redispatch
+registration events to the objects being registered. They depend on
+being dispatched to by the object-event dispatcher:
+
+ >>> from zope import component
+ >>> import zope.component.event
+ >>> zope.component.provideHandler(zope.component.event.objectEventNotify)
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Registered event:
+ HandlerRegistration(<BaseGlobalComponents base>,
+ [IObjectEvent], u'', objectEventNotify, u'')
+
+To see this, we'll first register a multi-handler to show is when
+handlers are called on 2 objects:
+
+ >>> @zope.component.adapter(None, None)
+ ... def double_handler(o1, o2):
+ ... print 'Double dispatch:'
+ ... print ' ', o1
+ ... print ' ', o2
+ >>> zope.component.provideHandler(double_handler)
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Double dispatch:
+ HandlerRegistration(<BaseGlobalComponents base>,
+ [Interface, Interface], u'', double_handler, u'')
+ Registered event:
+ HandlerRegistration(<BaseGlobalComponents base>,
+ [Interface, Interface], u'', double_handler, u'')
+ Registered event:
+ HandlerRegistration(<BaseGlobalComponents base>,
+ [Interface, Interface], u'', double_handler, u'')
+
+In the example above, the double_handler reported it's own registration. :)
+
+Now we'll register our handlers:
+
+ >>> zope.component.provideHandler(
+ ... registry.dispatchUtilityRegistrationEvent)
+ ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+ Double dispatch:
+ ...
+
+ >>> zope.component.provideHandler(
+ ... registry.dispatchAdapterRegistrationEvent)
+ ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+ Double dispatch:
+ ...
+
+ >>> zope.component.provideHandler(
+ ... registry.dispatchSubscriptionAdapterRegistrationEvent)
+ ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
+ Double dispatch:
+ ...
+
+ >>> zope.component.provideHandler(
+ ... registry.dispatchHandlerRegistrationEvent)
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Double dispatch:
+ HandlerRegistration(<BaseGlobalComponents base>,
+ [IHandlerRegistration, IRegistrationEvent], u'',
+ dispatchHandlerRegistrationEvent, u'')
+ Registered event:
+ HandlerRegistration(<BaseGlobalComponents base>,
+ [IHandlerRegistration, IRegistrationEvent], u'',
+ dispatchHandlerRegistrationEvent, u'')
+ Double dispatch:
+ <function dispatchHandlerRegistrationEvent at 0xb799f72c>
+ Registered event:
+ HandlerRegistration(<BaseGlobalComponents base>,
+ [IHandlerRegistration, IRegistrationEvent], u'',
+ dispatchHandlerRegistrationEvent, u'')
+ Registered event:
+ HandlerRegistration(<BaseGlobalComponents base>,
+ [IHandlerRegistration, IRegistrationEvent], u'',
+ dispatchHandlerRegistrationEvent, u'')
+
+In the last example above, we can see that the registration of
+dispatchHandlerRegistrationEvent was handled by
+dispatchHandlerRegistrationEvent and redispatched. This can be seen
+in the second double-dispatch output, where the first argument is the
+object being registered, which is dispatchHandlerRegistrationEvent.
+
+If we change some other registrations, we can the double dispatch
+taking place:
+
+ >>> components.registerUtility(u5)
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Double dispatch:
+ UtilityRegistration(<Components comps>, I1, u'', 5, u'')
+ Registered event:
+ UtilityRegistration(<Components comps>, I1, u'', 5, u'')
+ Double dispatch:
+ U1(5)
+ Registered event:
+ UtilityRegistration(<Components comps>, I1, u'', 5, u'')
+ Registered event:
+ UtilityRegistration(<Components comps>, I1, u'', 5, u'')
+
+ >>> components.registerAdapter(tests.A12_1)
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Double dispatch:
+ AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
+ Registered event:
+ AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
+ Double dispatch:
+ zope.component.tests.A12_1
+ Registered event:
+ AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
+ Registered event:
+ AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
+
+ >>> components.registerSubscriptionAdapter(tests.A1_2)
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Double dispatch:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, u'')
+ Registered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, u'')
+ Double dispatch:
+ zope.component.tests.A1_2
+ Registered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, u'')
+ Registered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, u'')
More information about the Zope3-Checkins
mailing list