[Checkins] SVN: zope.component/branches/tlotze-component-API/src/zope/component/ implemented a component hook and added a few tests that use the new adapt and utility methods on interfaces
Thomas Lotze
tl at gocept.com
Mon Dec 14 05:38:23 EST 2009
Log message for revision 106481:
implemented a component hook and added a few tests that use the new adapt and utility methods on interfaces
Changed:
U zope.component/branches/tlotze-component-API/src/zope/component/README.txt
U zope.component/branches/tlotze-component-API/src/zope/component/_api.py
-=-
Modified: zope.component/branches/tlotze-component-API/src/zope/component/README.txt
===================================================================
--- zope.component/branches/tlotze-component-API/src/zope/component/README.txt 2009-12-14 10:37:45 UTC (rev 106480)
+++ zope.component/branches/tlotze-component-API/src/zope/component/README.txt 2009-12-14 10:38:23 UTC (rev 106481)
@@ -35,7 +35,8 @@
In this example we registered the utility as providing the `IGreeter`
interface with a name of 'bob'. We can look the interface up with
-either `queryUtility` or `getUtility`:
+either `queryUtility` or `getUtility` as well as calling the `utility` method
+of the provided interface:
>>> component.queryUtility(IGreeter, 'robert').greet()
Hello bob
@@ -43,8 +44,12 @@
>>> component.getUtility(IGreeter, 'robert').greet()
Hello bob
-`queryUtility` and `getUtility` differ in how failed lookups are handled:
+ >>> IGreeter.utility(name='robert').greet()
+ Hello bob
+`queryUtility`, `getUtility` and `Interface.utility` differ in how failed
+lookups are handled:
+
>>> component.queryUtility(IGreeter, 'ted')
>>> component.queryUtility(IGreeter, 'ted', 42)
42
@@ -53,6 +58,11 @@
Traceback (most recent call last):
...
ComponentLookupError: (<InterfaceClass ...IGreeter>, 'ted')
+ >>> IGreeter.utility(name='ted', default=42)
+ 42
+ >>> IGreeter.utility(name='ted')
+ Traceback (most recent call last):
+ TypeError: ('Could not find utility', <InterfaceClass __builtin__.IGreeter>, {'name': 'ted'})
If a component provides only one interface, as in the example above,
then we can omit the provided interface from the call to `provideUtility`:
@@ -68,6 +78,8 @@
>>> component.provideUtility(world)
>>> component.queryUtility(IGreeter).greet()
Hello world
+ >>> IGreeter.utility().greet()
+ Hello world
Adapters
--------
@@ -146,7 +158,7 @@
... factory=TedPersonGreeter, adapts=[IPerson],
... provides=IGreeter, name='ted')
-For named adapters, use `queryAdapter`, or `getAdapter`:
+For named adapters, use `queryAdapter`, `getAdapter` or `Interface.adapt`:
>>> component.queryAdapter(Person("Sally"), IGreeter, 'bob').greet()
Hello Sally my name is Bob
@@ -154,8 +166,11 @@
>>> component.getAdapter(Person("Sally"), IGreeter, 'ted').greet()
Hello Sally my name is Ted
+ >>> IGreeter.adapt(Person("Sally"), name='ted').greet()
+ Hello Sally my name is Ted
+
If an adapter can't be found, `queryAdapter` returns a default value
-and `getAdapter` raises an error:
+and both `getAdapter` and `Interface.adapt` raise an error:
>>> component.queryAdapter(Person("Sally"), IGreeter, 'frank')
>>> component.queryAdapter(Person("Sally"), IGreeter, 'frank', 42)
@@ -165,6 +180,12 @@
Traceback (most recent call last):
...
ComponentLookupError: (...Person...>, <...IGreeter>, 'frank')
+ >>> IGreeter.adapt(Person("Sally"), name='frank', default=42)
+ 42
+ >>> IGreeter.adapt(Person("Sally"), name='frank')
+ ... # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ TypeError: ('Could not adapt', (<__builtin__.Person instance at 0x...>,), <InterfaceClass __builtin__.IGreeter>, {'name': 'frank'})
Adapters can adapt multiple objects:
@@ -183,13 +204,16 @@
>>> component.provideAdapter(TwoPersonGreeter)
-To look up a multi-adapter, use either `queryMultiAdapter` or
-`getMultiAdapter`:
+To look up a multi-adapter, use either `queryMultiAdapter`, `getMultiAdapter`
+or `Interface.adapt`:
>>> component.queryMultiAdapter((Person("Sally"), Person("Bob")),
... IGreeter).greet()
Hello Sally
my name is Bob
+ >>> IGreeter.adapt(Person("Sally"), Person("Bob")).greet()
+ Hello Sally
+ my name is Bob
Adapters need not be classes. Any callable will do. We use the
adapter decorator (in the Python 2.4 decorator sense) to declare that
Modified: zope.component/branches/tlotze-component-API/src/zope/component/_api.py
===================================================================
--- zope.component/branches/tlotze-component-API/src/zope/component/_api.py 2009-12-14 10:37:45 UTC (rev 106480)
+++ zope.component/branches/tlotze-component-API/src/zope/component/_api.py 2009-12-14 10:38:23 UTC (rev 106481)
@@ -161,7 +161,23 @@
zope.interface.interface.adapter_hooks.append(adapter_hook)
#############################################################################
+ at hookable
+def component_hook(interface, objects,
+ name='', default=None, context=None, **ignored):
+ try:
+ sitemanager = getSiteManager(context)
+ except ComponentLookupError:
+ # Oh blast, no site manager. This should *never* happen!
+ return None
+ if objects:
+ return sitemanager.queryMultiAdapter(
+ objects, interface, name, default)
+ else:
+ return sitemanager.queryUtility(interface, name, default)
+zope.interface.interface.component_hooks.append(component_hook)
+
+
# Utility API
def getUtility(interface, name='', context=None):
More information about the checkins
mailing list