[Zope3-checkins]
SVN: Zope3/branches/jim-adapter/src/zope/component/
Added registration events.
Jim Fulton
jim at zope.com
Sun Apr 2 13:00:12 EDT 2006
Log message for revision 66323:
Added registration events.
Registrations now include a registry attribute, indicating where they
came from.
All registries now have names and a repr that includes the name.
Moved ObjectEvent/IObjectEvent to zope.component.interfaces.
Eventually, we'll move the object dispatching code here.
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
U Zope3/branches/jim-adapter/src/zope/component/tests.py
-=-
Modified: Zope3/branches/jim-adapter/src/zope/component/interfaces.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/component/interfaces.py 2006-04-02 17:00:10 UTC (rev 66322)
+++ Zope3/branches/jim-adapter/src/zope/component/interfaces.py 2006-04-02 17:00:12 UTC (rev 66323)
@@ -17,9 +17,8 @@
"""
import zope.deferredimport
-from zope.interface import Interface, Attribute
+from zope import interface
-
# BBB: Backward-compatibility; 12/05/2004
from bbb.interfaces import *
@@ -32,7 +31,27 @@
class Misused(Exception):
"""A component is being used (registered) for the wrong interface."""
-class IComponentArchitecture(Interface):
+
+class IObjectEvent(interface.Interface):
+ """An event related to an object.
+
+ The object that generated this event is not necessarily the object
+ refered to by location.
+ """
+
+ object = interface.Attribute("The subject of the event.")
+
+
+class ObjectEvent(object):
+ interface.implements(IObjectEvent)
+
+ def __init__(self, object):
+ self.object = object
+
+ def __repr__(self):
+ return "%s event:\n%r" % (self.__class__.__name__, self.object)
+
+class IComponentArchitecture(interface.Interface):
"""The Component Architecture is defined by two key components: Adapters
and Utiltities. Both are managed by site managers. All other components
build on top of them.
@@ -51,9 +70,10 @@
If `context` is `None`, return the global site manager.
- If the `context` is not `None`, it is expected that an adapter from
- the `context` to `IComponentLookup` can be found. If no adapter is found,
- a `ComponentLookupError` is raised.
+ If the `context` is not `None`, it is expected that an adapter
+ from the `context` to `IComponentLookup` can be found. If no
+ adapter is found, a `ComponentLookupError` is raised.
+
"""
# Utility API
@@ -90,7 +110,9 @@
# Adapter API
- def getAdapter(object, interface=Interface, name=u'', context=None):
+ def getAdapter(object,
+ interface=interface.Interface, name=u'',
+ context=None):
"""Get a named adapter to an interface for an object
Returns an adapter that can adapt object to interface. If a matching
@@ -125,7 +147,9 @@
returned.
"""
- def getMultiAdapter(objects, interface=Interface, name='', context=None):
+ def getMultiAdapter(objects,
+ interface=interface.Interface, name='',
+ context=None):
"""Look for a multi-adapter to an interface for an objects
Returns a multi-adapter that can adapt objects to interface. If a
@@ -142,7 +166,7 @@
named adapter methods with an empty string for a name.
"""
- def queryAdapter(object, interface=Interface, name=u'', default=None,
+ def queryAdapter(object, interface=interface.Interface, name=u'', default=None,
context=None):
"""Look for a named adapter to an interface for an object
@@ -178,7 +202,9 @@
returned.
"""
- def queryMultiAdapter(objects, interface=Interface, name=u'', default=None,
+ def queryMultiAdapter(objects,
+ interface=interface.Interface, name=u'',
+ default=None,
context=None):
"""Look for a multi-adapter to an interface for objects
@@ -271,18 +297,18 @@
create objects which implement the given interface.
"""
-class IComponentLookup(Interface):
+class IComponentLookup(interface.Interface):
"""Component Manager for a Site
This object manages the components registered at a particular site. The
definition of a site is intentionally vague.
"""
- adapters = Attribute("Adapter Registry to manage all registered "
- "adapters.")
+ adapters = interface.Attribute(
+ "Adapter Registry to manage all registered adapters.")
- utilities = Attribute("Adapter Registry to manage all registered "
- "utilities.")
+ utilities = interface.Attribute(
+ "Adapter Registry to manage all registered utilities.")
def queryAdapter(object, interface, name=u'', default=None):
"""Look for a named adapter to an interface for an object
@@ -357,7 +383,7 @@
ISiteManager = "zope.component.interfaces:IComponentLookup",
)
-class IComponentRegistrationConvenience(Interface):
+class IComponentRegistrationConvenience(interface.Interface):
"""API for registering components.
CAUTION: This API should only be used from test or
@@ -439,7 +465,7 @@
activity.
"""
-class IRegistry(Interface):
+class IRegistry(interface.Interface):
"""Object that supports component registry
"""
@@ -447,12 +473,12 @@
"""Return an iterable of component registrations
"""
-class IFactory(Interface):
+class IFactory(interface.Interface):
"""A factory is responsible for creating other components."""
- title = Attribute("The factory title.")
+ title = interface.Attribute("The factory title.")
- description = Attribute("A brief description of the factory.")
+ description = interface.Attribute("A brief description of the factory.")
def __call__(*args, **kw):
"""Return an instance of the objects we're a factory for."""
@@ -466,8 +492,86 @@
instance cannot be created, an empty Implements instance is returned.
"""
+class IRegistration(interface.Interface):
+ """A registration-information object
+ """
-class IComponentRegistry(Interface):
+ registry = interface.Attribute("The registry having the registration")
+
+ name = interface.Attribute("The registration name")
+
+ info = interface.Attribute("""Information about the registration
+
+ This is information deemed useful to people browsing the
+ configuration of a system. It could, for example, include
+ commentary or information about the source of the configuration.
+ """)
+
+class IUtilityRegistration(IRegistration):
+ """Information about the registration of a utility
+ """
+
+ component = interface.Attribute("The object registered")
+ provided = interface.Attribute("The interface provided by the component")
+
+class IAdapterRegistration(IRegistration):
+ """Information about the registration of an adapter
+ """
+
+ factory = interface.Attribute("The factory used to create adapters")
+
+ required = interface.Attribute("""The adapted interfaces
+
+ This is a sequence of interfaces adapters by the registered
+ factory. The factory will be caled with a sequence of objects, as
+ positional arguments, that provide these interfaces.
+ """)
+
+ provided = interface.Attribute("""The interface provided by the adapters.
+
+ This interface is implemented by the factory
+ """)
+
+class ISubscriptionAdapterRegistration(IAdapterRegistration):
+ """Information about the registration of a subscription adapter
+ """
+
+class IHandlerRegistration(IRegistration):
+
+ handler = interface.Attribute("An object called used to handle an event")
+
+ required = interface.Attribute("""The handled interfaces
+
+ This is a sequence of interfaces handled by the registered
+ handler. The handler will be caled with a sequence of objects, as
+ positional arguments, that provide these interfaces.
+ """)
+
+class IRegistrationEvent(IObjectEvent):
+ """An event that involves a registration"""
+
+class RegistrationEvent(ObjectEvent):
+ """There has been a change in a registration
+ """
+ interface.implements(IRegistrationEvent)
+
+class IRegistered(IRegistrationEvent):
+ """A component or factory was registered
+ """
+
+class Registered(RegistrationEvent):
+ interface.implements(IRegistered)
+
+class IUnregistered(IRegistrationEvent):
+ """A component or factory was registered
+ """
+
+class Unregistered(RegistrationEvent):
+ """A component or factory was registered
+ """
+ interface.implements(IUnregistered)
+
+class IComponentRegistry(interface.Interface):
"""Register components
"""
@@ -489,6 +593,8 @@
info
An object that can be converted to a string to provide
information about the registration.
+
+ A Registered event is generated with an IUtilityRegistration.
"""
def unregisterUtility(component=None, provided=None, name=u''):
@@ -514,25 +620,15 @@
name
The utility name.
+
+ An UnRegistered event is generated with an IUtilityRegistration.
"""
def registeredUtilities():
- """Return an iterable of utility-information objects
+ """Return an iterable of IUtilityRegistrations.
- The information objects will have attributes:
-
- provided
- The provided interface
-
- name
- The name
-
- component
- The registered component
-
- info
- An object that can be converted to a string to provide
- information about the registration.
+ These registrations describe the current utility registrations
+ in the object.
"""
def registerAdapter(factory, required=None, provided=None, name=u'',
@@ -568,6 +664,8 @@
info
An object that can be converted to a string to provide
information about the registration.
+
+ A Registered event is generated with an IAdapterRegistration.
"""
def unregisterAdapter(factory=None, required=None,
@@ -609,27 +707,15 @@
name
The adapter name.
+
+ An Unregistered event is generated with an IAdapterRegistration.
"""
def registeredAdapters():
- """Return an iterable of adapter-information objects
+ """Return an iterable of IAdapterRegistrations.
- The adapter information objects will have attributes:
-
- required
- An iterable of required interfaces
-
- provided
- The provided interface
-
- name
- The name
-
- factory
- The registered factory
-
- info
- Provide some info about this particular adapter registration.
+ These registrations describe the current adapter registrations
+ in the object.
"""
def registerSubscriptionAdapter(factory, required=None, provides=None,
@@ -668,6 +754,9 @@
info
An object that can be converted to a string to provide
information about the registration.
+
+ A Registered event is generated with an
+ ISubscriptionAdapterRegistration.
"""
def unregisterSubscriptionAdapter(factory=None, required=None,
@@ -712,28 +801,16 @@
Note that this parameter is ignored and is reserved
for future use when named subscribers are implemented.
+
+ An Unregistered event is generated with an
+ ISubscriptionAdapterRegistration.
"""
def registeredSubscriptionAdapters():
- """Return an iterable of subscriber-information objects
+ """Return an iterable of ISubscriptionAdapterRegistrations.
- The subscriber information objects will have attributes:
-
- required
- An iterable of required interfaces
-
- provided
- The provided interface
-
- name
- The name
-
- factory
- The registered factory
-
- info
- An object that can be converted to a string to provide
- information about the registration.
+ These registrations describe the current subscription adapter
+ registrations in the object.
"""
def registerHandler(handler, adapts=None, name=u'', info=''):
@@ -768,6 +845,9 @@
info
An object that can be converted to a string to provide
information about the registration.
+
+
+ A Registered event is generated with an IHandlerRegistration.
"""
def unregisterHandler(handler=None, adapts=None, name=u''):
@@ -801,27 +881,18 @@
Note that this parameter is ignored and is reserved
for future use when named handlers are implemented.
+
+ An Unregistered event is generated with an IHandlerRegistration.
"""
def registeredHandlers():
- """Return an iterable of handler-information objects
+ """Return an iterable of IHandlerRegistrations.
- The subscriber information objects will have attributes:
+ These registrations describe the current handler registrations
+ in the object.
+ """
- required
- An iterable of required interfaces
- name
- The name
-
- handler
- The registered handler
-
- info
- An object that can be converted to a string to provide
- information about the registration.
- """
-
class IComponents(IComponentLookup, IComponentRegistry):
"""Component registration and access
"""
Modified: Zope3/branches/jim-adapter/src/zope/component/registry.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/component/registry.py 2006-04-02 17:00:10 UTC (rev 66322)
+++ Zope3/branches/jim-adapter/src/zope/component/registry.py 2006-04-02 17:00:12 UTC (rev 66323)
@@ -21,16 +21,22 @@
from zope import interface
from zope.component import interfaces
import zope.interface.interfaces
+import zope.event
class Components(object):
interface.implements(interfaces.IComponents)
- def __init__(self, bases=()):
+ def __init__(self, name='', bases=()):
+ assert isinstance(name, basestring)
+ self.__name__ = name
self._init_registries()
self._init_registrations()
self.__bases__ = tuple(bases)
+ def __repr__(self):
+ return "<%s %s>" % (self.__class__.__name__, self.__name__)
+
def _init_registries(self):
self.adapters = zope.interface.adapter.AdapterRegistry()
self.utilities = zope.interface.adapter.AdapterRegistry()
@@ -75,6 +81,10 @@
if not subscribed:
self.utilities.subscribe((), provided, component)
+ zope.event.notify(interfaces.Registered(
+ UtilityRegistration(self, provided, name, component, info)
+ ))
+
def unregisterUtility(self, component=None, provided=None, name=u''):
if provided is None:
if component is None:
@@ -99,13 +109,17 @@
if not subscribed:
self.utilities.unsubscribe((), provided, component)
+
+ zope.event.notify(interfaces.Unregistered(
+ UtilityRegistration(self, provided, name, component, old[1])
+ ))
return True
def registeredUtilities(self):
for ((provided, name), (component, info)
) in self._utility_registrations.iteritems():
- yield UtilityRegistration(provided, name, component, info)
+ yield UtilityRegistration(self, provided, name, component, info)
def queryUtility(self, provided, name=u'', default=None):
return self.utilities.lookup((), provided, name, default)
@@ -133,7 +147,13 @@
self._adapter_registrations[(required, provided, name)
] = factory, info
self.adapters.register(required, provided, name, factory)
+
+ zope.event.notify(interfaces.Registered(
+ AdapterRegistration(self, required, provided, name,
+ factory, info)
+ ))
+
def unregisterAdapter(self, factory=None,
required=None, provided=None, name=u'',
):
@@ -153,12 +173,18 @@
del self._adapter_registrations[(required, provided, name)]
self.adapters.unregister(required, provided, name)
+
+ zope.event.notify(interfaces.Unregistered(
+ AdapterRegistration(self, required, provided, name,
+ *old)
+ ))
+
return True
def registeredAdapters(self):
for ((required, provided, name), (component, info)
) in self._adapter_registrations.iteritems():
- yield AdapterRegistration(required, provided, name,
+ yield AdapterRegistration(self, required, provided, name,
component, info)
def queryAdapter(self, object, interface, name=u'', default=None):
@@ -200,10 +226,15 @@
(required, provided, name, factory, info)
)
self.adapters.subscribe(required, provided, factory)
+
+ zope.event.notify(interfaces.Registered(
+ SubscriptionRegistration(self, required, provided, name,
+ factory, info)
+ ))
def registeredSubscriptionAdapters(self):
for data in self._subscription_registrations:
- yield SubscriptionRegistration(*data)
+ yield SubscriptionRegistration(self, *data)
def unregisterSubscriptionAdapter(self, factory=None,
required=None, provided=None, name=u'',
@@ -239,14 +270,17 @@
self._subscription_registrations = new
self.adapters.unsubscribe(required, provided)
+
+ zope.event.notify(interfaces.Unregistered(
+ SubscriptionRegistration(self, required, provided, name,
+ factory, '')
+ ))
+
return True
def subscribers(self, objects, provided):
return self.adapters.subscribers(objects, provided)
-
-
-
def registerHandler(self,
factory, required=None,
name=u'', info=u''):
@@ -257,10 +291,14 @@
(required, name, factory, info)
)
self.adapters.subscribe(required, None, factory)
+
+ zope.event.notify(interfaces.Registered(
+ HandlerRegistration(self, required, name, factory, info)
+ ))
def registeredHandlers(self):
for data in self._handler_registrations:
- yield HandlerRegistration(*data)
+ yield HandlerRegistration(self, *data)
def unregisterHandler(self, factory=None, required=None, name=u''):
if name:
@@ -289,6 +327,11 @@
self._handler_registrations = new
self.adapters.unsubscribe(required, None)
+
+ zope.event.notify(interfaces.Unregistered(
+ HandlerRegistration(self, required, name, factory, '')
+ ))
+
return True
def handle(self, *objects):
@@ -343,15 +386,16 @@
class UtilityRegistration(object):
- def __init__(self, provided, name, component, doc):
- (self.provided, self.name, self.component, self.info
- ) = provided, name, component, doc
+ def __init__(self, registry, provided, name, component, doc):
+ (self.registry, self.provided, self.name, self.component, self.info
+ ) = registry, provided, name, component, doc
def __repr__(self):
- return '%s(%r, %r, %r, %r)' % (
+ return '%s(%r, %s, %r, %s, %r)' % (
self.__class__.__name__,
+ self.registry,
getattr(self.provided, '__name__', None), self.name,
- getattr(self.component, '__name__', self.component), self.info,
+ getattr(self.component, '__name__', `self.component`), self.info,
)
def __cmp__(self, other):
@@ -359,29 +403,38 @@
class AdapterRegistration(object):
- def __init__(self, required, provided, name, component, doc):
- (self.required, self.provided, self.name, self.factory, self.info
- ) = required, provided, name, component, doc
+ def __init__(self, registry, required, provided, name, component, doc):
+ (self.registry, self.required, self.provided, self.name,
+ self.factory, self.info
+ ) = registry, required, provided, name, component, doc
def __repr__(self):
- return '%s(%r, %r, %r, %r, %r)' % (
+ return '%s(%r, %s, %s, %r, %s, %r)' % (
self.__class__.__name__,
- tuple([r.__name__ for r in self.required]),
+ self.registry,
+ '[' + ", ".join([r.__name__ for r in self.required]) + ']',
getattr(self.provided, '__name__', None), self.name,
- getattr(self.factory, '__name__', self.factory), self.info,
+ getattr(self.factory, '__name__', `self.factory`), self.info,
)
def __cmp__(self, other):
return cmp(self.__repr__(), other.__repr__())
+ @property
+ @zope.deprecation.deprecate(
+ "The component attribute on adapter registrations will be unsupported "
+ "in Zope 3.5. Use the factory attribute instead.")
+ def component(self):
+ return self.factory
+
class SubscriptionRegistration(AdapterRegistration):
pass
-class HandlerRegistration(object):
+class HandlerRegistration(AdapterRegistration):
- def __init__(self, required, name, handler, doc):
- (self.required, self.name, self.handler, self.info
- ) = required, name, handler, doc
+ def __init__(self, registry, required, name, handler, doc):
+ (self.registry, self.required, self.name, self.handler, self.info
+ ) = registry, required, name, handler, doc
@property
def factory(self):
@@ -390,10 +443,11 @@
provided = None
def __repr__(self):
- return '%s(%r, %r, %r, %r)' % (
+ return '%s(%r, %s, %r, %s, %r)' % (
self.__class__.__name__,
- tuple([r.__name__ for r in self.required]),
+ self.registry,
+ '[' + ", ".join([r.__name__ for r in self.required]) + ']',
self.name,
- getattr(self.factory, '__name__', self.factory), self.info,
+ getattr(self.factory, '__name__', `self.factory`), self.info,
)
Modified: Zope3/branches/jim-adapter/src/zope/component/registry.txt
===================================================================
--- Zope3/branches/jim-adapter/src/zope/component/registry.txt 2006-04-02 17:00:10 UTC (rev 66322)
+++ Zope3/branches/jim-adapter/src/zope/component/registry.txt 2006-04-02 17:00:12 UTC (rev 66323)
@@ -18,7 +18,15 @@
>>> from zope.component.registry import Components
>>> from zope.component import tests
- >>> components = Components()
+ >>> components = Components('comps')
+
+As components atr registered, events are generated. Let's register
+an event subscriber, so we can see the events generated:
+
+ >>> import zope.event
+ >>> def logevent(event):
+ ... print event
+ >>> zope.event.subscribers.append(logevent)
Utilities
---------
@@ -26,6 +34,8 @@
You can register Utilities using registerUtility:
>>> components.registerUtility(tests.U1(1))
+ Registered event:
+ UtilityRegistration(<Components comps>, I1, u'', 1, u'')
Here we didn't specify an interface or name. An unnamed utility was
registered for interface I1, since that is only interface implemented
@@ -55,10 +65,14 @@
We can provide an interface if desired:
>>> components.registerUtility(tests.U12(2), tests.I2)
+ Registered event:
+ UtilityRegistration(<Components comps>, I2, u'', 2, u'')
and we can specify a name:
>>> components.registerUtility(tests.U12(3), tests.I2, u'three')
+ Registered event:
+ UtilityRegistration(<Components comps>, I2, u'three', 3, u'')
>>> components.getUtility(tests.I2)
U12(2)
@@ -98,6 +112,8 @@
Duplicate registrations replace existing ones:
>>> components.registerUtility(tests.U1(4), info=u'use 4 now')
+ Registered event:
+ UtilityRegistration(<Components comps>, I1, u'', 4, u'use 4 now')
>>> components.getUtility(tests.I1)
U1(4)
@@ -118,6 +134,8 @@
You can also unregister utilities:
>>> components.unregisterUtility(provided=tests.I1)
+ Unregistered event:
+ UtilityRegistration(<Components comps>, I1, u'', 4, u'use 4 now')
True
A boolean is returned indicating whether anything changed:
@@ -136,11 +154,15 @@
>>> u5 = tests.U1(5)
>>> components.registerUtility(u5)
+ Registered event:
+ UtilityRegistration(<Components comps>, I1, u'', 5, u'')
>>> components.unregisterUtility(tests.U1(6))
False
>>> components.queryUtility(tests.I1)
U1(5)
>>> components.unregisterUtility(u5)
+ Unregistered event:
+ UtilityRegistration(<Components comps>, I1, u'', 5, u'')
True
>>> components.queryUtility(tests.I1)
@@ -150,6 +172,8 @@
You can register adapters with registerAdapter:
>>> components.registerAdapter(tests.A12_1)
+ Registered event:
+ AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
Here, we didn't specify required interfaces, a provided interface, or
a name. The required interfaces were determined from the factory
@@ -172,6 +196,8 @@
Unless the provided interface is specified:
>>> components.registerAdapter(tests.A1_12, provided=tests.IA2)
+ Registered event:
+ AdapterRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
If a factory doesn't declare an implemented interface, an exception will be
raised:
@@ -186,6 +212,8 @@
Unless the provided interface is specified:
>>> components.registerAdapter(tests.A12_, provided=tests.IA2)
+ Registered event:
+ AdapterRegistration(<Components comps>, [I1, I2], IA2, u'', A12_, u'')
If the required interface needs to be specified in the
registration if the factory doesn't have a __component_adapts__
@@ -201,12 +229,18 @@
Unless the required specifications specified:
>>> components.registerAdapter(tests.A_2, required=[tests.I3])
+ Registered event:
+ AdapterRegistration(<Components comps>, [I3], IA2, u'', A_2, u'')
Classes can be specified in place of specifications, in which case the
implementedBy specification for the class is used:
>>> components.registerAdapter(tests.A_3, required=[tests.U],
... info="Really class specific")
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Registered event:
+ AdapterRegistration(<Components comps>, [zope.component.tests.U], IA3, u'',
+ A_3, 'Really class specific')
We can see the adapters that have been registered using the
registeredAdapters method:
@@ -278,7 +312,10 @@
be provided:
>>> components.unregisterAdapter(tests.A12_1)
+ Unregistered event:
+ AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
True
+
>>> for regsitration in sorted(components.registeredAdapters()):
... print regsitration.required
... print regsitration.provided, regsitration.name
@@ -313,6 +350,8 @@
Unless the provided interface is specified:
>>> components.unregisterAdapter(tests.A1_12, provided=tests.IA2)
+ Unregistered event:
+ AdapterRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
True
If a factory doesn't declare an implemented interface, an exception will be
@@ -328,6 +367,8 @@
Unless the provided interface is specified:
>>> components.unregisterAdapter(tests.A12_, provided=tests.IA2)
+ Unregistered event:
+ AdapterRegistration(<Components comps>, [I1, I2], IA2, u'', A12_, u'')
True
The required interface needs to be specified if the factory doesn't
@@ -341,6 +382,8 @@
attribute and no required specifications were specified
>>> components.unregisterAdapter(tests.A_2, required=[tests.I3])
+ Unregistered event:
+ AdapterRegistration(<Components comps>, [I3], IA2, u'', A_2, u'')
True
>>> for regsitration in sorted(components.registeredAdapters()):
@@ -365,6 +408,10 @@
specified required and provided interfaces:
>>> components.unregisterAdapter(required=[tests.U], provided=tests.IA3)
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Unregistered event:
+ AdapterRegistration(<Components comps>, [zope.component.tests.U],
+ IA3, u'', A_3, 'Really class specific')
True
>>> for regsitration in sorted(components.registeredAdapters()):
@@ -374,6 +421,8 @@
>>> components.registerAdapter(tests.A1_12, provided=tests.IA2,
... name=u'test')
+ Registered event:
+ AdapterRegistration(<Components comps>, [I1], IA2, u'test', A1_12, u'')
>>> components.queryMultiAdapter((tests.U1(9), ), tests.IA2)
>>> components.queryMultiAdapter((tests.U1(9), ), tests.IA2, name=u'test')
@@ -390,8 +439,13 @@
>>> components.registerAdapter(tests.A1_23, provided=tests.IA2,
... name=u'test 2')
+ Registered event:
+ AdapterRegistration(<Components comps>, [I1], IA2, u'test 2', A1_23, u'')
>>> components.registerAdapter(tests.A1_12, provided=tests.IA2)
+ Registered event:
+ AdapterRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
+
>>> for name, adapter in sorted(components.getAdapters((tests.U1(9), ),
... tests.IA2)):
... print name, adapter
@@ -408,9 +462,16 @@
>>> components.registerAdapter(tests.noop,
... required=[tests.IA1], provided=tests.IA2,
... name=u'test noop')
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Registered event:
+ AdapterRegistration(<Components comps>, [IA1], IA2, u'test noop',
+ noop, u'')
>>> components.queryAdapter(tests.U1(9), tests.IA2, name=u'test noop')
>>> components.registerAdapter(tests.A1_12, provided=tests.IA2)
+ Registered event:
+ AdapterRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
+
>>> for name, adapter in sorted(components.getAdapters((tests.U1(9), ),
... tests.IA2)):
... print name, adapter
@@ -420,9 +481,13 @@
>>> components.unregisterAdapter(tests.A1_12, provided=tests.IA2,
- ... name=u'test')
+ ... name=u'test')
+ Unregistered event:
+ AdapterRegistration(<Components comps>, [I1], IA2, u'test', A1_12, u'')
True
>>> components.unregisterAdapter(tests.A1_12, provided=tests.IA2)
+ Unregistered event:
+ AdapterRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
True
>>> for regsitration in sorted(components.registeredAdapters()):
... print regsitration.required
@@ -446,14 +511,24 @@
Subscribers are registered by calling registerSubscriptionAdapter:
- >>> components.registerSubscriptionAdapter(tests.A1_2)
+ >>> components.registerSubscriptionAdapter(tests.A1_2)
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Registered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, u'')
- >>> components.registerSubscriptionAdapter(
- ... tests.A1_12, provided=tests.IA2)
+ >>> components.registerSubscriptionAdapter(
+ ... tests.A1_12, provided=tests.IA2)
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Registered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
- >>> components.registerSubscriptionAdapter(
- ... tests.A, [tests.I1], tests.IA2,
- ... info='a sample comment')
+ >>> components.registerSubscriptionAdapter(
+ ... tests.A, [tests.I1], tests.IA2,
+ ... info='a sample comment')
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Registered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'',
+ A, 'a sample comment')
The same rules, with regard to when required and provided interfaces
have to be specified apply as with adapters:
@@ -485,6 +560,10 @@
>>> components.registerSubscriptionAdapter(
... tests.A, [tests.I1], tests.IA2, u'', 'a sample comment')
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Registered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'',
+ A, 'a sample comment')
>>> components.registerSubscriptionAdapter(
... tests.A, [tests.I1], tests.IA2, u'oops', 'a sample comment')
@@ -506,8 +585,10 @@
As with normal adapters, if a factory returns None, the result is skipped:
- >>> components.registerSubscriptionAdapter(
- ... tests.noop, [tests.I1], tests.IA2)
+ >>> components.registerSubscriptionAdapter(
+ ... tests.noop, [tests.I1], tests.IA2)
+ Registered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'', noop, u'')
>>> for s in components.subscribers((tests.U1(1), ), tests.IA2):
... print s
@@ -542,6 +623,9 @@
We can also unregister subscriptions in much the same way we can for adapters:
>>> components.unregisterSubscriptionAdapter(tests.A1_2)
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Unregistered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, '')
True
>>> for registration in sorted(
@@ -564,6 +648,8 @@
>>> components.unregisterSubscriptionAdapter(
... tests.A, [tests.I1], tests.IA2)
+ Unregistered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A, '')
True
>>> for registration in sorted(
@@ -594,6 +680,8 @@
>>> components.unregisterSubscriptionAdapter(
... required=[tests.I1], provided=tests.IA2)
+ Unregistered event:
+ SubscriptionRegistration(<Components comps>, [I1], IA2, u'', None, '')
True
>>> for registration in sorted(
@@ -624,7 +712,8 @@
TypeError: The adapter factory doesn't implement a single interface
and no provided interface was specified.
-If you unregister something that's not registered, nothing will be changed and False will be returned:
+If you unregister something that's not registered, nothing will be
+changed and False will be returned:
>>> components.unregisterSubscriptionAdapter(
@@ -644,6 +733,10 @@
... print 'handle1', x
>>> components.registerHandler(handle1, info="First handler")
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Registered event:
+ HandlerRegistration(<Components comps>, [I1], u'',
+ handle1, 'First handler')
>>> components.handle(tests.U1(1))
handle1 U1(1)
@@ -652,6 +745,8 @@
... print 'handle12', x, y
>>> components.registerHandler(handle12)
+ Registered event:
+ HandlerRegistration(<Components comps>, [I1, I2], u'', handle12, u'')
>>> components.handle(tests.U1(1), tests.U12(2))
handle12 U1(1) U12(2)
@@ -670,11 +765,17 @@
>>> components.registerHandler(handle, required=[tests.I1],
... info="a comment")
+ Registered event:
+ HandlerRegistration(<Components comps>, [I1], u'', handle, 'a comment')
Handlers can also be registered for classes:
>>> components.registerHandler(handle, required=[tests.U],
... info="handle a class")
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Registered event:
+ HandlerRegistration(<Components comps>, [zope.component.tests.U], u'',
+ handle, 'handle a class')
>>> components.handle(tests.U1(1))
@@ -701,6 +802,10 @@
and we can unregister handlers:
>>> components.unregisterHandler(required=[tests.U])
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Unregistered event:
+ HandlerRegistration(<Components comps>, [zope.component.tests.U], u'',
+ None, '')
True
>>> for registration in components.registeredHandlers():
@@ -716,6 +821,8 @@
<function handle at 0xb78f5ca4> a comment
>>> components.unregisterHandler(handle12)
+ Unregistered event:
+ HandlerRegistration(<Components comps>, [I1, I2], u'', handle12, '')
True
>>> for registration in components.registeredHandlers():
@@ -747,50 +854,72 @@
Component-management objects can extend other component-management
objects.
- >>> c1 = Components()
+ >>> c1 = Components('1')
>>> c1.__bases__
()
- >>> c2 = Components((c1, ))
+ >>> c2 = Components('2', (c1, ))
>>> c2.__bases__ == (c1, )
True
>>> c1.registerUtility(tests.U1(1))
+ Registered event:
+ UtilityRegistration(<Components 1>, I1, u'', 1, u'')
+
>>> c1.queryUtility(tests.I1)
U1(1)
>>> c2.queryUtility(tests.I1)
U1(1)
>>> c1.registerUtility(tests.U1(2))
+ Registered event:
+ UtilityRegistration(<Components 1>, I1, u'', 2, u'')
+
>>> c2.queryUtility(tests.I1)
U1(2)
We can use multiple inheritence:
- >>> c3 = Components((c1, ))
- >>> c4 = Components((c2, c3))
+ >>> c3 = Components('3', (c1, ))
+ >>> c4 = Components('4', (c2, c3))
>>> c4.queryUtility(tests.I1)
U1(2)
>>> c1.registerUtility(tests.U12(1), tests.I2)
+ Registered event:
+ UtilityRegistration(<Components 1>, I2, u'', 1, u'')
+
>>> c4.queryUtility(tests.I2)
U12(1)
>>> c3.registerUtility(tests.U12(3), tests.I2)
+ Registered event:
+ UtilityRegistration(<Components 3>, I2, u'', 3, u'')
>>> c4.queryUtility(tests.I2)
U12(3)
>>> c1.registerHandler(handle1, info="First handler")
+ Registered event:
+ HandlerRegistration(<Components 1>, [I1], u'', handle1, 'First handler')
+
>>> c2.registerHandler(handle, required=[tests.U])
+ ... # doctest: +NORMALIZE_WHITESPACE
+ Registered event:
+ HandlerRegistration(<Components 2>, [zope.component.tests.U], u'',
+ handle, u'')
>>> @component.adapter(tests.I1)
... def handle3(x):
... print 'handle3', x
>>> c3.registerHandler(handle3)
+ Registered event:
+ HandlerRegistration(<Components 3>, [I1], u'', handle3, u'')
>>> @component.adapter(tests.I1)
... def handle4(x):
... print 'handle4', x
>>> c4.registerHandler(handle4)
+ Registered event:
+ HandlerRegistration(<Components 4>, [I1], u'', handle4, u'')
>>> c4.handle(tests.U1(1))
handle1 U1(1)
Modified: Zope3/branches/jim-adapter/src/zope/component/tests.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/component/tests.py 2006-04-02 17:00:10 UTC (rev 66322)
+++ Zope3/branches/jim-adapter/src/zope/component/tests.py 2006-04-02 17:00:12 UTC (rev 66323)
@@ -710,19 +710,19 @@
>>> from zope.component.persistentregistry import PersistentComponents
>>> _ = t1.begin()
- >>> r1[1] = PersistentComponents()
+ >>> r1[1] = PersistentComponents('1')
>>> t1.commit()
>>> _ = t2.begin()
- >>> r2[2] = PersistentComponents((r2[1], ))
+ >>> r2[2] = PersistentComponents('2', (r2[1], ))
>>> t2.commit()
>>> _ = t1.begin()
- >>> r1[3] = PersistentComponents((r1[1], ))
+ >>> r1[3] = PersistentComponents('3', (r1[1], ))
>>> t1.commit()
>>> _ = t2.begin()
- >>> r2[4] = PersistentComponents((r2[2], r2[3]))
+ >>> r2[4] = PersistentComponents('4', (r2[2], r2[3]))
>>> t2.commit()
>>> _ = t1.begin()
@@ -789,6 +789,10 @@
>>> db.close()
"""
+def tearDownRegistryTests(tests):
+ import zope.event
+ zope.event.subscribers.pop()
+
def test_suite():
checker = renormalizing.RENormalizing([
(re.compile('at 0x[0-9a-f]+'), 'at <SOME ADDRESS>'),
@@ -803,7 +807,8 @@
setUp=setUp, tearDown=tearDown),
doctest.DocFileSuite('factory.txt',
setUp=setUp, tearDown=tearDown),
- doctest.DocFileSuite('registry.txt', checker=checker),
+ doctest.DocFileSuite('registry.txt', checker=checker,
+ tearDown=tearDownRegistryTests),
))
if __name__ == "__main__":
More information about the Zope3-Checkins
mailing list