[Zope3-checkins] SVN: Zope3/trunk/src/zope/ Made the for_ attribute
optional in the adapter directive if
Jim Fulton
jim at zope.com
Thu Jan 27 19:10:01 EST 2005
Log message for revision 28967:
Made the for_ attribute optional in the adapter directive if
the factory declares what it adapts. For classes, this declaration is
made using the zope.component.adapts function.
Made the provides attribute optional in the adapter directive if the
registered factory implements exactly one interface.
Made the provides attribute optional in the utility directive if the
registered component provides exactly one interface.
Changed:
U Zope3/trunk/src/zope/app/component/metaconfigure.py
U Zope3/trunk/src/zope/app/component/metadirectives.py
U Zope3/trunk/src/zope/app/component/tests/adapter.py
U Zope3/trunk/src/zope/app/component/tests/test_directives.py
U Zope3/trunk/src/zope/component/tests/components.py
-=-
Modified: Zope3/trunk/src/zope/app/component/metaconfigure.py
===================================================================
--- Zope3/trunk/src/zope/app/component/metaconfigure.py 2005-01-27 18:48:53 UTC (rev 28966)
+++ Zope3/trunk/src/zope/app/component/metaconfigure.py 2005-01-28 00:10:00 UTC (rev 28967)
@@ -20,6 +20,7 @@
from zope.component.interfaces import IDefaultViewName, IFactory
from zope.component.service import UndefinedService
from zope.configuration.exceptions import ConfigurationError
+import zope.interface
from zope.interface import Interface
from zope.interface.interfaces import IInterface
@@ -128,16 +129,37 @@
args = ('', iface)
)
-def adapter(_context, factory, provides, for_, permission=None, name='',
- trusted=False):
+def adapter(_context, factory, provides=None, for_=None, permission=None,
+ name='', trusted=False):
+
if permission is not None:
if permission == PublicPermission:
permission = CheckerPublic
checker = InterfaceChecker(provides, permission)
factory.append(lambda c: proxify(c, checker))
+ if for_ is None:
+ if len(factory) == 1:
+ try:
+ for_ = factory[0].__component_adapts__
+ except AttributeError:
+ pass
+
+ if for_ is None:
+ raise TypeError("No for attribute was provided and can't "
+ "determine what the factory adapts.")
+
for_ = tuple(for_)
+ if provides is None:
+ if len(factory) == 1:
+ p = list(zope.interface.implementedBy(factory[0]))
+ if len(p) == 1:
+ provides = p[0]
+
+ if provides is None:
+ raise TypeError("Missing 'provides' attribute")
+
# Generate a single factory from multiple factories:
factories = factory
if len(factories) == 1:
@@ -177,13 +199,20 @@
args = ('', iface)
)
-def utility(_context, provides, component=None, factory=None,
+def utility(_context, provides=None, component=None, factory=None,
permission=None, name=''):
if factory:
if component:
raise TypeError("Can't specify factory and component.")
component = factory()
+ if provides is None:
+ provides = list(zope.interface.providedBy(component))
+ if len(provides) == 1:
+ provides = provides[0]
+ else:
+ raise TypeError("Missing 'provides' attribute")
+
if permission is not None:
if permission == PublicPermission:
permission = CheckerPublic
Modified: Zope3/trunk/src/zope/app/component/metadirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/component/metadirectives.py 2005-01-27 18:48:53 UTC (rev 28966)
+++ Zope3/trunk/src/zope/app/component/metadirectives.py 2005-01-28 00:10:00 UTC (rev 28967)
@@ -172,13 +172,13 @@
title=_("Interface the component provides"),
description=_("This attribute specifes the interface the adapter"
" instance must provide."),
- required=True
+ required=False,
)
for_ = zope.configuration.fields.Tokens(
title=_("Specifications to be adapted"),
description=_("This should be a list of interfaces or classes"),
- required=True,
+ required=False,
value_type=zope.configuration.fields.GlobalObject(
missing_value=object(),
),
@@ -267,7 +267,7 @@
provides = zope.configuration.fields.GlobalInterface(
title=_("Provided interface"),
description=_("Interface provided by the utility."),
- required=True
+ required=False,
)
name = zope.schema.TextLine(
Modified: Zope3/trunk/src/zope/app/component/tests/adapter.py
===================================================================
--- Zope3/trunk/src/zope/app/component/tests/adapter.py 2005-01-27 18:48:53 UTC (rev 28966)
+++ Zope3/trunk/src/zope/app/component/tests/adapter.py 2005-01-28 00:10:00 UTC (rev 28967)
@@ -17,6 +17,8 @@
"""
import zope.interface
+import zope.component
+import zope.component.tests.components
class I1(zope.interface.Interface):
pass
@@ -42,9 +44,19 @@
zope.interface.implements(I2)
class A3(Adapter):
+ zope.component.adapts(zope.component.tests.components.IContent, I1, I2)
zope.interface.implements(I3)
+class A4:
+ pass
+a4 = A4()
+
+class A5:
+ zope.interface.implements(I1, I2)
+
+a5 = A5()
+
def Handler(content, *args):
# uninteresting handler
content.args = getattr(content, 'args', ()) + (args, )
Modified: Zope3/trunk/src/zope/app/component/tests/test_directives.py
===================================================================
--- Zope3/trunk/src/zope/app/component/tests/test_directives.py 2005-01-27 18:48:53 UTC (rev 28966)
+++ Zope3/trunk/src/zope/app/component/tests/test_directives.py 2005-01-28 00:10:00 UTC (rev 28967)
@@ -236,6 +236,48 @@
self.assertEqual(IApp(Content()).__class__, Comp)
+ def testAdapter_wo_provides_or_for(self):
+ # Full import is critical!
+ from zope.component.tests.components import Content, IApp, Comp
+
+ self.assertEqual(IV(Content(), None), None)
+
+ xmlconfig(StringIO(template % (
+ """
+ <adapter
+ factory="zope.component.tests.components.Comp"
+ />
+ """
+ )))
+
+ self.assertEqual(IApp(Content()).__class__, Comp)
+
+ def testAdapter_wo_provides_and_no_implented_fails(self):
+ try:
+ xmlconfig(StringIO(template % (
+ """
+ <adapter
+ factory="zope.app.component.tests.adapter.A4"
+ for="zope.component.tests.components.IContent"
+ />
+ """
+ )))
+ except ConfigurationError, v:
+ self.assert_("Missing 'provides' attribute" in str(v))
+
+ def testAdapter_wo_provides_and_too_many_implented_fails(self):
+ try:
+ xmlconfig(StringIO(template % (
+ """
+ <adapter
+ factory="zope.app.component.tests.adapter.A4"
+ for="zope.component.tests.components.IContent"
+ />
+ """
+ )))
+ except ConfigurationError, v:
+ self.assert_("Missing 'provides' attribute" in str(v))
+
def testTrustedAdapter(self):
# Full import is critical!
from zope.component.tests.components import Content
@@ -341,6 +383,26 @@
self.assertEqual(a3.__class__, A3)
self.assertEqual(a3.context, (content, a1, a2))
+ def testMultiAdapter_wo_for_or_provides(self):
+ from zope.app.component.tests.adapter import A1, A2, A3, I3
+ from zope.component.tests.components import Content
+
+ xmlconfig(StringIO(template % (
+ """
+ <adapter
+ factory="zope.app.component.tests.adapter.A3
+ "
+ />
+ """
+ )))
+
+ content = Content()
+ a1 = A1()
+ a2 = A2()
+ a3 = zapi.queryMultiAdapter((content, a1, a2), I3)
+ self.assertEqual(a3.__class__, A3)
+ self.assertEqual(a3.context, (content, a1, a2))
+
def testNullAdapter(self):
from zope.app.component.tests.adapter import A3, I3
@@ -472,6 +534,71 @@
self.assertEqual(zapi.getUtility(IApp), comp)
+ def testUtility_wo_provides(self):
+
+ # Full import is critical!
+ from zope.component.tests.components import IApp, comp
+
+ self.assertEqual(zapi.queryUtility(IV), None)
+
+ xmlconfig(StringIO(template % (
+ """
+ <utility
+ component="zope.component.tests.components.comp"
+ />
+ """
+ )))
+
+ self.assertEqual(zapi.getUtility(IApp), comp)
+
+ def testUtility_wo_provides_fails_if_no_provides(self):
+ try:
+ xmlconfig(StringIO(template % (
+ """
+ <utility
+ component="zope.app.component.tests.adapter.a4"
+ />
+ """
+ )))
+ except ConfigurationError, v:
+ self.assert_("Missing 'provides' attribute" in str(v))
+
+ def testUtility_wo_provides_fails_if_too_many_provided(self):
+ try:
+ xmlconfig(StringIO(template % (
+ """
+ <utility
+ component="zope.app.component.tests.adapter.a5"
+ />
+ """
+ )))
+ except ConfigurationError, v:
+ self.assert_("Missing 'provides' attribute" in str(v))
+
+ def testUtility_wo_provides_fails_if_no_implemented(self):
+ try:
+ xmlconfig(StringIO(template % (
+ """
+ <utility
+ factory="zope.app.component.tests.adapter.A4"
+ />
+ """
+ )))
+ except ConfigurationError, v:
+ self.assert_("Missing 'provides' attribute" in str(v))
+
+ def testUtility_wo_provides_fails_if_too_many_implemented(self):
+ try:
+ xmlconfig(StringIO(template % (
+ """
+ <utility
+ factory="zope.app.component.tests.adapter.A5"
+ />
+ """
+ )))
+ except ConfigurationError, v:
+ self.assert_("Missing 'provides' attribute" in str(v))
+
def testNamedUtility(self):
# Full import is critical!
Modified: Zope3/trunk/src/zope/component/tests/components.py
===================================================================
--- Zope3/trunk/src/zope/component/tests/components.py 2005-01-27 18:48:53 UTC (rev 28966)
+++ Zope3/trunk/src/zope/component/tests/components.py 2005-01-28 00:10:00 UTC (rev 28967)
@@ -16,6 +16,7 @@
$Id$
"""
from zope.interface import Interface, Attribute, implements
+from zope.component import adapts
class RecordingAdapter(object):
@@ -50,7 +51,7 @@
implements(IContent)
class Comp(object):
- __used_for__ = IContent
+ adapts(IContent)
implements(IApp)
def __init__(self, *args):
More information about the Zope3-Checkins
mailing list