Re: improving the utility and adapter lookup APIs

Shane Hathaway <[email protected]>
Newsgroups gmane.comp.web.zope.devel
Message-ID <[email protected]>
Martijn Faassen wrote:
> But someone needs to think of a feasible upgrade scenario. We could 
> instrument all calls to IFoo and see whether a default argument is in 
> use, but what then? I'd be hard to distinguish a default argument from 
> one we're meant to adapt. I'd also be non-trivial to scan code.

Here is an interface decorator I intend to try out soon.  It adds 
convenient component lookup methods to a particular interface without 
requiring any changes to zope.interface.

--- (snip) ---

from zope.interface.interfaces import IInterface
from zope.component import getAdapter
from zope.component import getMultiAdapter
from zope.component import getUtility
from zope.component import queryAdapter
from zope.component import queryMultiAdapter
from zope.component import queryUtility

def componentlookup(iface):
     """Decorator: adds zope.component lookup methods to an interface.

     Adds utility([default], [name]) and adapt(*args, [default], [name]).
     """
     assert IInterface.providedBy(iface)

     def utility(**kw):
         if 'default' in kw:
             return queryUtility(iface, **kw)
         else:
             return getUtility(iface, **kw)
     iface.utility = utility

     def adapt(*args, **kw):
         if len(args) == 1:
             # simple adapter lookup
             arg = args[0]
             if not 'name' in kw and iface.providedBy(arg):
                 # The object passed in already provides this interface,
                 # and no adapter name was provided, so return the object
                 # unchanged.
                 return arg
             if 'default' in kw:
                 return queryAdapter(arg, iface, **kw)
             else:
                 return getAdapter(arg, iface, **kw)

         # multi-adapter lookup
         if 'default' in kw:
             return queryMultiAdapter(args, iface, **kw)
         else:
             return getMultiAdapter(args, iface, **kw)
     iface.adapt = adapt

     return iface


--- (snip) ---

Example usage:

     @componentlookup
     class IFoo(Interface):
         pass

     class Foo(object):
         implements(IFoo)

     IFoo.adapt(Foo())
     IFoo.adapt(Foo(), HTTPRequest(), name='edit')
     IFoo.adapt(Foo(), name='x')
     IFoo.adapt(Foo(), default=None)
     IFoo.utility(default=None)

I think class decorators were added in Python 2.6, but in earlier 
Pythons you can do this instead:

     class IFoo(Interface):
         pass
     componentlookup(IFoo)

Shane
_______________________________________________
Zope-Dev maillist  -  [email protected]
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.