[Checkins] SVN: grokcore.component/trunk/ Add support for registering global adapters at module level via a global_adapter() directive
Martin Aspeli
optilude at gmx.net
Thu Apr 9 11:16:37 EDT 2009
Log message for revision 99034:
Add support for registering global adapters at module level via a global_adapter() directive
Changed:
U grokcore.component/trunk/CHANGES.txt
U grokcore.component/trunk/src/grokcore/component/__init__.py
U grokcore.component/trunk/src/grokcore/component/directive.py
U grokcore.component/trunk/src/grokcore/component/meta.py
A grokcore.component/trunk/src/grokcore/component/tests/adapter/globaladapter.py
-=-
Modified: grokcore.component/trunk/CHANGES.txt
===================================================================
--- grokcore.component/trunk/CHANGES.txt 2009-04-09 15:14:35 UTC (rev 99033)
+++ grokcore.component/trunk/CHANGES.txt 2009-04-09 15:16:37 UTC (rev 99034)
@@ -4,10 +4,19 @@
1.6 (unreleased)
----------------
+* Add support for registering global adapters at module level::
+
+ grok.global_adapter(factory, (IAdapted1, IAdapted2,), IProvided, name=u"name")
+
+ Only 'factory' is required. If only a single interface is adapted, the
+ second argument may be a single interface instead of a tuple. If the
+ component has declared adapted/provided interfaces, the second and third
+ arguments may be omitted.
+
* Add support for an @provider decorator to let a function directly provide
an interface::
- @provider(IFoo, IBar)
+ @grok.provider(IFoo, IBar)
def some_function():
...
@@ -15,7 +24,7 @@
* Add support for named adapters with the @adapter decorator::
- @adapter(IAdaptedOne, IAdaptedTwo, name=u"foo")
+ @grok.adapter(IAdaptedOne, IAdaptedTwo, name=u"foo")
def some_function(one, two):
...
Modified: grokcore.component/trunk/src/grokcore/component/__init__.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/__init__.py 2009-04-09 15:14:35 UTC (rev 99033)
+++ grokcore.component/trunk/src/grokcore/component/__init__.py 2009-04-09 15:16:37 UTC (rev 99034)
@@ -22,7 +22,7 @@
from martian import baseclass
from grokcore.component.directive import (
- context, name, title, description, provides, global_utility, direct)
+ context, name, title, description, provides, global_utility, global_adapter, direct)
from grokcore.component.decorators import subscribe, adapter, implementer, provider
from martian.error import GrokError, GrokImportError
Modified: grokcore.component/trunk/src/grokcore/component/directive.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/directive.py 2009-04-09 15:14:35 UTC (rev 99033)
+++ grokcore.component/trunk/src/grokcore/component/directive.py 2009-04-09 15:16:37 UTC (rev 99034)
@@ -36,6 +36,33 @@
name = grokcore.component.name.bind().get(factory)
return (factory, provides, name, direct)
+class global_adapter(martian.MultipleTimesDirective):
+ scope = martian.MODULE
+
+ def factory(self, factory, adapts=None, provides=None, name=u''):
+ if provides is not None and not IInterface.providedBy(provides):
+ raise GrokImportError(
+ "You can only pass an interface to the "
+ "provides argument of %s." % self.name)
+
+ if provides is None:
+ provides = grokcore.component.provides.bind().get(factory)
+
+ if adapts is None:
+ adapts = getattr(factory, '__component_adapts__', None)
+ if adapts is None:
+ adapts = grokcore.component.context.bind().get(factory)
+
+ if not isinstance(adapts, (list, tuple,)):
+ adapts = (adapts,)
+ elif isinstance(adapts, list):
+ adapts = tuple(adapts)
+
+ if not name:
+ name = grokcore.component.name.bind().get(factory)
+
+ return (factory, adapts, provides, name)
+
class name(martian.Directive):
scope = martian.CLASS
store = martian.ONCE
@@ -61,4 +88,4 @@
class provides(martian.Directive):
scope = martian.CLASS
store = martian.ONCE
- validate = martian.validateInterface
+ validate = martian.validateInterface
\ No newline at end of file
Modified: grokcore.component/trunk/src/grokcore/component/meta.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/meta.py 2009-04-09 15:14:35 UTC (rev 99033)
+++ grokcore.component/trunk/src/grokcore/component/meta.py 2009-04-09 15:16:37 UTC (rev 99034)
@@ -156,7 +156,20 @@
return True
+class GlobalAdapterDirectiveGrokker(martian.GlobalGrokker):
+ def grok(self, name, module, module_info, config, **kw):
+ infos = grokcore.component.global_adapter.bind().get(module=module)
+
+ for factory, adapts, provides, name in infos:
+ config.action(
+ discriminator=('adapter', adapts, provides, name),
+ callable=component.provideAdapter,
+ args=(factory, adapts, provides, name),
+ )
+
+ return True
+
class SubscriberGrokker(martian.GlobalGrokker):
def grok(self, name, module, module_info, config, **kw):
Added: grokcore.component/trunk/src/grokcore/component/tests/adapter/globaladapter.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/adapter/globaladapter.py (rev 0)
+++ grokcore.component/trunk/src/grokcore/component/tests/adapter/globaladapter.py 2009-04-09 15:16:37 UTC (rev 99034)
@@ -0,0 +1,89 @@
+"""
+ >>> grok.testing.grok(__name__)
+ >>> from zope.component import getAdapter, getMultiAdapter
+
+ >>> cave = Cave()
+ >>> fireplace = Fireplace()
+
+ >>> home = IHome(cave)
+ >>> home.id
+ u'one'
+
+ >>> home = getAdapter(cave, IHome, name=u"two")
+ >>> home.id
+ u'two'
+
+ >>> home = getAdapter(cave, IHome, name=u"three")
+ >>> home.id
+ u'three'
+
+ >>> home = getAdapter(cave, IHome, name=u"four")
+ >>> home.id
+ u'four'
+
+ >>> home = getAdapter(fireplace, IHome, name=u"five")
+ >>> home.id
+ u'five'
+
+ >>> home = getMultiAdapter((cave, fireplace), IHome)
+ >>> home.id
+ u'six'
+
+"""
+
+import grokcore.component as grok
+from zope import interface
+
+class Cave(grok.Context):
+ pass
+
+class Fireplace(object):
+ pass
+
+class IHome(interface.Interface):
+ pass
+
+class Home(object):
+ grok.implements(IHome)
+
+ def __init__(self, id):
+ self.id = id
+
+class CaveHomeFactory(object):
+ grok.implements(IHome)
+
+ def __init__(self, id):
+ self.id = id
+
+ def __call__(self, context):
+ return Home(self.id)
+
+class CaveFireplaceHomeFactory(object):
+ def __init__(self, id):
+ self.id = id
+
+ def __call__(self, cave, fireplace):
+ return Home(self.id)
+
+factory1 = CaveHomeFactory(u"one")
+factory2 = CaveHomeFactory(u"two")
+factory3 = CaveHomeFactory(u"three")
+factory4 = CaveHomeFactory(u"four")
+factory5 = CaveHomeFactory(u"five")
+factory6 = CaveFireplaceHomeFactory(u"six")
+
+# make some direct assertions
+
+grok.implementer(IHome)(factory3)
+grok.implementer(IHome)(factory4)
+grok.implementer(IHome)(factory5)
+grok.implementer(IHome)(factory6)
+
+grok.adapter(Fireplace)(factory5)
+
+grok.global_adapter(factory1, Cave, IHome) # should accept single value for adapts
+grok.global_adapter(factory2, (Cave,), IHome, name="two") # should accept tuple for adapts
+grok.global_adapter(factory3, Cave, name="three") # should look at the provided interface
+grok.global_adapter(factory4, name=u"four") # should pick the canonical context
+grok.global_adapter(factory5, name="five") # should use __component_adapts__
+grok.global_adapter(factory6, (Cave, Fireplace,)) # should work as multi-adapter
More information about the Checkins
mailing list