[Zope-dev] improving the utility and adapter lookup APIs
Shane Hathaway
shane at hathawaymix.org
Thu Nov 26 05:53:39 EST 2009
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
More information about the Zope-Dev
mailing list