[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