[Zope3-checkins] SVN: Zope3/trunk/src/zope/ Added a decorater for declaring that non-class objects adapt

Jim Fulton jim at zope.com
Thu Feb 17 12:25:22 EST 2005


Log message for revision 29176:
  Added a decorater for declaring that non-class objects adapt
  interfaces (or classes).
  

Changed:
  U   Zope3/trunk/src/zope/component/README.txt
  U   Zope3/trunk/src/zope/component/__init__.py
  U   Zope3/trunk/src/zope/interface/README.txt

-=-
Modified: Zope3/trunk/src/zope/component/README.txt
===================================================================
--- Zope3/trunk/src/zope/component/README.txt	2005-02-17 17:25:20 UTC (rev 29175)
+++ Zope3/trunk/src/zope/component/README.txt	2005-02-17 17:25:22 UTC (rev 29176)
@@ -179,7 +179,51 @@
     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
+a callable object adapts some interfaces (or classes):
 
+    >>> class IJob(zope.interface.Interface):
+    ...     "A job"
+
+    >>> class Job:
+    ...     zope.interface.implements(IJob)
+
+    >>> def personJob(person):
+    ...     return getattr(person, 'job', None)
+    >>> personJob = zope.interface.implementer(IJob)(personJob)
+    >>> personJob = zope.component.adapter(IPerson)(personJob)
+
+(In Python 2.4, the example can be written:
+
+    @zope.interface.implementer(IJob)
+    @zope.component.adapter(IPerson)
+    def personJob(person):
+        return getattr(person, 'job', None)
+
+which looks a bit nicer.
+
+In this example, the personJob function simply returns the person's
+`job` attribute if present, or None if it's not present.  An adapter
+factory can return None to indicate that adaptation wasn't possible.
+Let's register this adapter and try it out:
+
+    >>> zope.component.provideAdapter(personJob)
+    >>> sally = Person("Sally")
+    >>> IJob(sally) # doctest: +ELLIPSIS
+    Traceback (most recent call last):
+    ...
+    TypeError: ('Could not adapt', ...
+
+The adaptation failed because sally didn't have a job.  Let's give her
+one: 
+
+    >>> job = Job()
+    >>> sally.job = job
+    >>> IJob(sally) is job
+    True
+ 
+
 .. [1] CAUTION: This API should only be used from test or
        application-setup code. This API shouldn't be used by regular
        library modules, as component registration is a configuration

Modified: Zope3/trunk/src/zope/component/__init__.py
===================================================================
--- Zope3/trunk/src/zope/component/__init__.py	2005-02-17 17:25:20 UTC (rev 29175)
+++ Zope3/trunk/src/zope/component/__init__.py	2005-02-17 17:25:22 UTC (rev 29176)
@@ -17,6 +17,7 @@
 """
 import sys
 import zope.interface
+from types import ClassType
 from zope.interface import moduleProvides, Interface
 from zope.interface import providedBy, implementedBy
 from zope.component.interfaces import IComponentArchitecture
@@ -27,6 +28,8 @@
 from zope.component.interfaces import ComponentLookupError
 from zope.component.site import globalSiteManager
 
+_class_types = type, ClassType
+
 ##############################################################################
 # BBB: Import some backward-compatibility; 12/10/2004
 from zope.component.bbb import exceptions
@@ -186,6 +189,20 @@
             return self.interfaces
         raise AttributeError, '__component_adapts__'
 
+class adapter:
+
+    def __init__(self, *interfaces):
+        self.interfaces = interfaces
+
+    def __call__(self, ob):
+        if isinstance(ob, _class_types):
+            ob.__component_adapts__ = _adapts_descr(self.interfaces)
+        else:
+            ob.__component_adapts__ = self.interfaces
+
+        return ob
+
+
 def adapts(*interfaces):
     frame = sys._getframe(1)
     locals = frame.f_locals

Modified: Zope3/trunk/src/zope/interface/README.txt
===================================================================
--- Zope3/trunk/src/zope/interface/README.txt	2005-02-17 17:25:20 UTC (rev 29175)
+++ Zope3/trunk/src/zope/interface/README.txt	2005-02-17 17:25:22 UTC (rev 29176)
@@ -226,7 +226,7 @@
   ...     foo = Foo()
   ...     foo.y = y
   ...     return foo
-  >>> zope.interface.implementer(IFoo)(yfoo)
+  >>> yfoo = zope.interface.implementer(IFoo)(yfoo)
 
   >>> list(zope.interface.implementedBy(yfoo))
   [<InterfaceClass __main__.IFoo>]



More information about the Zope3-Checkins mailing list