[Checkins] SVN: grok/trunk/src/grok/ Merge adapter decorator
functionality.
Jan-Wijbrand Kolman
jw at infrae.com
Thu Jun 21 16:01:53 EDT 2007
Log message for revision 76919:
Merge adapter decorator functionality.
Changed:
U grok/trunk/src/grok/__init__.py
U grok/trunk/src/grok/_grok.py
U grok/trunk/src/grok/meta.py
A grok/trunk/src/grok/tests/adapter/adapterdecorator.py
A grok/trunk/src/grok/tests/adapter/functionasargument_fixture.py
A grok/trunk/src/grok/tests/adapter/noarguments_fixture.py
-=-
Modified: grok/trunk/src/grok/__init__.py
===================================================================
--- grok/trunk/src/grok/__init__.py 2007-06-21 19:36:37 UTC (rev 76918)
+++ grok/trunk/src/grok/__init__.py 2007-06-21 20:01:52 UTC (rev 76919)
@@ -40,6 +40,7 @@
define_permission, require, site)
from grok._grok import do_grok as grok # Avoid name clash within _grok
from grok._grok import SubscribeDecorator as subscribe
+from grok._grok import adapter, implementer
from grok.error import GrokError, GrokImportError
from grok.formlib import action, AutoFields, Fields
from grok.util import url
Modified: grok/trunk/src/grok/_grok.py
===================================================================
--- grok/trunk/src/grok/_grok.py 2007-06-21 19:36:37 UTC (rev 76918)
+++ grok/trunk/src/grok/_grok.py 2007-06-21 20:01:52 UTC (rev 76919)
@@ -15,6 +15,7 @@
"""
import os
import sys
+import types
from zope import component
from zope import interface
@@ -105,3 +106,30 @@
if subscribers is None:
frame.f_locals['__grok_subscribers__'] = subscribers = []
subscribers.append((function, self.subscribed))
+
+from zope.component._declaration import adapter as _adapter
+class adapter(_adapter):
+
+ def __init__(self, *interfaces):
+ # Override the z.c.adapter decorator to force sanity checking
+ # and have better error reporting.
+ if not interfaces:
+ raise GrokImportError(
+ "@grok.adapter requires at least one argument.")
+ if type(interfaces[0]) is types.FunctionType:
+ raise GrokImportError(
+ "@grok.adapter requires at least one argument.")
+ self.interfaces = interfaces
+
+from zope.interface.declarations import implementer as _implementer
+class implementer(_implementer):
+
+ def __call__(self, ob):
+ # XXX we do not have function grokkers (yet) so we put the annotation
+ # on the module.
+ frame = sys._getframe(1)
+ implementers = frame.f_locals.get('__implementers__', None)
+ if implementers is None:
+ frame.f_locals['__implementers__'] = implementers = []
+ implementers.append(ob)
+ return _implementer.__call__(self, ob)
Modified: grok/trunk/src/grok/meta.py
===================================================================
--- grok/trunk/src/grok/meta.py 2007-06-21 19:36:37 UTC (rev 76918)
+++ grok/trunk/src/grok/meta.py 2007-06-21 20:01:52 UTC (rev 76919)
@@ -90,7 +90,7 @@
methods = util.methods_from_class(factory)
default_permission = util.get_default_permission(factory)
-
+
for method in methods:
# Make sure that the class inherits MethodPublisher, so that the
# views have a location
@@ -109,7 +109,7 @@
permission = getattr(method, '__grok_require__',
default_permission)
util.make_checker(factory, method_view, permission)
-
+
class ViewGrokker(grok.ClassGrokker):
component_class = grok.View
@@ -175,7 +175,7 @@
# protect view, public by default
default_permission = util.get_default_permission(factory)
util.make_checker(factory, factory, default_permission)
-
+
# safety belt: make sure that the programmer didn't use
# @grok.require on any of the view's methods.
methods = util.methods_from_class(factory)
@@ -195,7 +195,7 @@
methods = util.methods_from_class(factory)
default_permission = util.get_default_permission(factory)
-
+
for method in methods:
# Create a new class with a __view_name__ attribute so the
# JSON class knows what method to call.
@@ -258,7 +258,20 @@
for iface in subscribed:
zope.component.interface.provideInterface('', iface)
+class AdapterDecoratorGrokker(grok.ModuleGrokker):
+ def register(self, context, module_info, templates):
+ implementers = module_info.getAnnotation('implementers', [])
+ for function in implementers:
+ interfaces = getattr(function, '__component_adapts__', None)
+ if interfaces is None:
+ # There's no explicit interfaces defined, so we assume the
+ # module context to be the thing adapted.
+ util.check_context(module_info.getModule(), context)
+ interfaces = (context, )
+ component.provideAdapter(
+ function, adapts=interfaces, provides=function.__implemented__)
+
class StaticResourcesGrokker(grok.ModuleGrokker):
def register(self, context, module_info, templates):
@@ -429,10 +442,10 @@
if setup is not None:
setup(utility)
-
+
site_manager.registerUtility(utility, provided=provides,
name=name)
-
+
class DefinePermissionGrokker(grok.ModuleGrokker):
priority = 1500
@@ -452,7 +465,7 @@
class AnnotationGrokker(grok.ClassGrokker):
component_class = grok.Annotation
-
+
def register(self, context, name, factory, module_info, templates):
adapter_context = util.determine_class_context(factory, context)
provides = util.class_annotation(factory, 'grok.provides', None)
@@ -518,14 +531,14 @@
context, module_info),
adapts=(site,
grok.IObjectAddedEvent))
-
+
class IndexesSetupSubscriber(object):
def __init__(self, catalog_name, indexes, context, module_info):
self.catalog_name = catalog_name
self.indexes = indexes
self.context = context
self.module_info = module_info
-
+
def __call__(self, site, event):
# make sure we have an intids
self._createIntIds(site)
@@ -555,7 +568,7 @@
catalog = Catalog()
setupUtility(site, catalog, ICatalog, name=self.catalog_name)
return catalog
-
+
def _createIntIds(self, site):
"""Create intids if needed, and return it.
"""
Added: grok/trunk/src/grok/tests/adapter/adapterdecorator.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/adapterdecorator.py (rev 0)
+++ grok/trunk/src/grok/tests/adapter/adapterdecorator.py 2007-06-21 20:01:52 UTC (rev 76919)
@@ -0,0 +1,71 @@
+"""
+ >>> grok.grok(__name__)
+ >>>
+ >>> cave = Cave()
+ >>> home = IHome(cave)
+ >>> IHome.providedBy(home)
+ True
+ >>>
+ >>> isinstance(home, Home)
+ True
+ >>> morehome = IMoreHome(cave)
+ >>> IHome.providedBy(morehome)
+ True
+ >>> isinstance(morehome, Home)
+ True
+ >>> yetanotherhome = IYetAnotherHome(cave)
+ >>> IHome.providedBy(yetanotherhome)
+ True
+ >>> isinstance(yetanotherhome, Home)
+ True
+
+ >>> from grok.tests.adapter import noarguments_fixture
+ Traceback (most recent call last):
+ ...
+ GrokImportError: @grok.adapter requires at least one argument.
+
+ >>> from grok.tests.adapter import functionasargument_fixture
+ Traceback (most recent call last):
+ ...
+ GrokImportError: @grok.adapter requires at least one argument.
+
+"""
+
+import grok
+from zope import interface
+
+class IDummy(interface.Interface):
+ pass
+
+class ICave(interface.Interface):
+ pass
+
+class IHome(interface.Interface):
+ pass
+
+class IMoreHome(interface.Interface):
+ pass
+
+class IYetAnotherHome(interface.Interface):
+ pass
+
+class Cave(grok.Model):
+ grok.implements(ICave)
+ pass
+
+class Home(object):
+ grok.implements(IHome)
+
+ at grok.adapter(Cave)
+ at grok.implementer(IHome)
+def home_for_cave(cave):
+ return Home()
+
+ at grok.adapter(ICave)
+ at grok.implementer(IMoreHome)
+def more_home_for_cave(cave):
+ return Home()
+
+ at grok.implementer(IYetAnotherHome)
+def yet_another_home_for_cave(cave):
+ return Home()
Added: grok/trunk/src/grok/tests/adapter/functionasargument_fixture.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/functionasargument_fixture.py (rev 0)
+++ grok/trunk/src/grok/tests/adapter/functionasargument_fixture.py 2007-06-21 20:01:52 UTC (rev 76919)
@@ -0,0 +1,10 @@
+import grok
+from zope import interface
+
+class IDummy(interface.Interface):
+ pass
+
+ at grok.adapter
+ at grok.implementer(IDummy)
+def decorator_called_with_function_as_argument(cave):
+ pass
Added: grok/trunk/src/grok/tests/adapter/noarguments_fixture.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/noarguments_fixture.py (rev 0)
+++ grok/trunk/src/grok/tests/adapter/noarguments_fixture.py 2007-06-21 20:01:52 UTC (rev 76919)
@@ -0,0 +1,10 @@
+import grok
+from zope import interface
+
+class IDummy(interface.Interface):
+ pass
+
+ at grok.adapter()
+ at grok.implementer(IDummy)
+def decorator_called_with_no_arguments(cave):
+ pass
More information about the Checkins
mailing list