[Checkins] SVN: grok/trunk/ Merged the
jw-philipp-using-ndir-directives branch.
Philipp von Weitershausen
philikon at philikon.de
Sun May 4 11:27:38 EDT 2008
Log message for revision 86390:
Merged the jw-philipp-using-ndir-directives branch.
Changed:
U grok/trunk/setup.py
U grok/trunk/src/grok/__init__.py
U grok/trunk/src/grok/admin/view.py
U grok/trunk/src/grok/components.py
U grok/trunk/src/grok/directive.py
U grok/trunk/src/grok/ftests/catalog/indexes_multiple_conflict.py
D grok/trunk/src/grok/ftests/grok_component.txt
U grok/trunk/src/grok/ftests/test_grok_functional.py
U grok/trunk/src/grok/ftests/utility/local.py
U grok/trunk/src/grok/meta.py
U grok/trunk/src/grok/templatereg.py
U grok/trunk/src/grok/testing.py
U grok/trunk/src/grok/tests/adapter/classcontextmultiple.py
U grok/trunk/src/grok/tests/adapter/classorinterface.py
U grok/trunk/src/grok/tests/adapter/functioncontext.py
U grok/trunk/src/grok/tests/adapter/importedmodel2.py
U grok/trunk/src/grok/tests/adapter/modulecontextmultiple.py
U grok/trunk/src/grok/tests/adapter/multiadaptsnone.py
U grok/trunk/src/grok/tests/adapter/multiple.py
U grok/trunk/src/grok/tests/adapter/nomodel.py
U grok/trunk/src/grok/tests/baseclass/base.py
D grok/trunk/src/grok/tests/baseclass/basecontext.py
U grok/trunk/src/grok/tests/directive/argumenterror.py
U grok/trunk/src/grok/tests/directive/argumenterror_fixture.py
U grok/trunk/src/grok/tests/directive/multipleasdict.py
U grok/trunk/src/grok/tests/directive/multipletimes.py
U grok/trunk/src/grok/tests/grokker/grokcomponent.py
U grok/trunk/src/grok/tests/json/nocontext.py
A grok/trunk/src/grok/tests/order/
U grok/trunk/src/grok/tests/security/not_a_permissionclass.py
U grok/trunk/src/grok/tests/test_grok.py
D grok/trunk/src/grok/tests/util/class_annotation.py
U grok/trunk/src/grok/tests/utility/local_implementsmany.py
A grok/trunk/src/grok/tests/utility/local_implementsmany_fixture.py
U grok/trunk/src/grok/tests/utility/local_implementsnone.py
U grok/trunk/src/grok/tests/utility/local_implementsnone2.py
A grok/trunk/src/grok/tests/utility/local_implementsnone2_fixture.py
A grok/trunk/src/grok/tests/utility/local_implementsnone_fixture.py
U grok/trunk/src/grok/tests/utility/multiple_class.py
A grok/trunk/src/grok/tests/utility/multiple_class_fixture.py
U grok/trunk/src/grok/tests/utility/multiple_directive.py
A grok/trunk/src/grok/tests/utility/multiple_directive_fixture.py
U grok/trunk/src/grok/tests/view/ambiguouscontext.py
U grok/trunk/src/grok/tests/view/missingcontext.py
U grok/trunk/src/grok/tests/view/namemultiple.py
U grok/trunk/src/grok/tests/view/nameunicode.py
U grok/trunk/src/grok/tests/view/nomodulename.py
U grok/trunk/src/grok/tests/viewlet/viewlet_ambiguous_manager.py
U grok/trunk/src/grok/tests/xmlrpc/nocontext.py
U grok/trunk/src/grok/tests/zcml/directiveerror.py
U grok/trunk/src/grok/tests/zcml/directiveimporterror.py
U grok/trunk/src/grok/util.py
U grok/trunk/versions.cfg
-=-
Modified: grok/trunk/setup.py
===================================================================
--- grok/trunk/setup.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/setup.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -35,8 +35,8 @@
include_package_data = True,
zip_safe=False,
install_requires=['setuptools',
- 'martian >= 0.9.3',
- 'grokcore.component >= 1.1',
+ 'martian >= 0.9.4',
+ 'grokcore.component >= 1.2',
'simplejson',
'pytz',
'ZODB3',
Modified: grok/trunk/src/grok/__init__.py
===================================================================
--- grok/trunk/src/grok/__init__.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/__init__.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -44,11 +44,12 @@
from grok.interfaces import IRESTSkinType
from grok.components import ViewletManager, Viewlet
+from martian import baseclass
from grokcore.component.directive import (
- context, name, title, provides, baseclass, global_utility, direct, order)
+ context, name, title, description, provides, global_utility, direct)
from grok.directive import (
template, templatedir, local_utility, permissions, require, site,
- layer, viewletmanager, view, traversable)
+ layer, viewletmanager, view, traversable, order)
from grokcore.component.decorators import subscribe, adapter, implementer
from martian.error import GrokError, GrokImportError
Modified: grok/trunk/src/grok/admin/view.py
===================================================================
--- grok/trunk/src/grok/admin/view.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/admin/view.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -143,7 +143,7 @@
obj = self.context
result = ""
while obj is not None:
- if __grok_context__.providedBy(obj):
+ if IRootFolder.providedBy(obj):
return self.url(obj, name)
obj = obj.__parent__
raise ValueError("No application nor root element found.")
Modified: grok/trunk/src/grok/components.py
===================================================================
--- grok/trunk/src/grok/components.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/components.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -52,9 +52,10 @@
from zope.viewlet.manager import ViewletManagerBase
from zope.viewlet.viewlet import ViewletBase
+import grok
+import grokcore.component
import z3c.flashmessage.interfaces
import martian.util
-import grokcore.component.util
from grok import interfaces, formlib, util
@@ -436,7 +437,7 @@
if subob is not None:
return util.safely_locate_maybe(subob, self.context, name)
- traversable_dict = getattr(self.context, '__grok_traversable__', None)
+ traversable_dict = grok.traversable.get(self.context)
if traversable_dict:
if name in traversable_dict:
subob = getattr(self.context, traversable_dict[name])
@@ -621,15 +622,13 @@
def __init__(self, name, bases=(), attrs=None):
if attrs is None:
return
- # make sure we take over a bunch of possible attributes
- for name in ['__grok_context__', '__grok_name__',
- '__grok_site__']:
- value = attrs.get(name)
- if value is not None:
- setattr(self, name, value)
- # now read and store indexes
indexes = {}
for name, value in attrs.items():
+ # Ignore everything that's not an index definition object
+ # except for values set by directives
+ if '.' in name:
+ setattr(self, name, value)
+ continue
if not interfaces.IIndexDefinition.providedBy(value):
continue
indexes[name] = value
@@ -667,9 +666,8 @@
def __init__(self, context, request, view):
super(ViewletManager, self).__init__(context, request, view)
- self.__name__ = util.class_annotation(self.__class__,
- 'grok.name',
- self.__class__.__name__.lower())
+ self.__name__ = util.get_name_classname(self.__class__)
+
self.static = component.queryAdapter(
self.request,
interface.Interface,
@@ -682,7 +680,7 @@
if self.template:
return self.template.render(self)
else:
- viewlets = grokcore.component.util.sort_components(self.viewlets)
+ viewlets = util.sort_components(self.viewlets)
return u'\n'.join([viewlet.render() for viewlet in viewlets])
def namespace(self):
@@ -722,9 +720,8 @@
super(Viewlet, self).__init__(context, request, view, manager)
# would be nice to move this to the ViewletGrokker but
# new objects don't have __name__ of their class
- self.__name__ = util.class_annotation(self.__class__,
- 'grok.name',
- self.__class__.__name__.lower())
+ self.__name__ = util.get_name_classname(self.__class__)
+
self.static = component.queryAdapter(
self.request,
interface.Interface,
Modified: grok/trunk/src/grok/directive.py
===================================================================
--- grok/trunk/src/grok/directive.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/directive.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -14,107 +14,183 @@
"""Grok directives.
"""
+import sys
+import grok
+from zope import interface
from zope.interface.interfaces import IInterface
+from zope.publisher.interfaces.browser import IBrowserView
-from martian.error import GrokImportError
-from martian.directive import (Directive, OnceDirective,
- MultipleTimesDirective, BaseTextDirective,
- SingleValue, SingleTextDirective,
- MultipleTextDirective,
- MarkerDirective,
- InterfaceDirective,
- InterfaceOrClassDirective,
- ModuleDirectiveContext,
- OptionalValueDirective,
- ClassDirectiveContext,
- ClassOrModuleDirectiveContext)
+import martian
from martian import util
-from grokcore.component.directive import MultiValueOnceDirective
+from martian.error import GrokImportError, GrokError
+from martian.directive import StoreMultipleTimes
from grok import components
-class LocalUtilityDirective(MultipleTimesDirective):
- def check_arguments(self, factory, provides=None, name=u'',
- setup=None, public=False, name_in_container=None):
+# Define grok directives
+class template(martian.Directive):
+ scope = martian.CLASS
+ store = martian.ONCE
+ validate = martian.validateText
+
+class templatedir(martian.Directive):
+ scope = martian.MODULE
+ store = martian.ONCE
+ validate = martian.validateText
+
+class local_utility(martian.Directive):
+ scope = martian.CLASS
+ store = martian.DICT
+
+ def factory(self, factory, provides=None, name=u'',
+ setup=None, public=False, name_in_container=None):
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)
- def value_factory(self, *args, **kw):
- return LocalUtilityInfo(*args, **kw)
+ if provides is None:
+ provides = grok.provides.get(factory)
+ if provides is None:
+ if util.check_subclass(factory, grok.LocalUtility):
+ baseInterfaces = interface.implementedBy(grok.LocalUtility)
+ utilityInterfaces = interface.implementedBy(factory)
+ provides = list(utilityInterfaces - baseInterfaces)
+ if len(provides) == 0 and len(list(utilityInterfaces)) > 0:
+ raise GrokImportError(
+ "Cannot determine which interface to use "
+ "for utility registration of %r. "
+ "It implements an interface that is a specialization "
+ "of an interface implemented by grok.LocalUtility. "
+ "Specify the interface by either using grok.provides "
+ "on the utility or passing 'provides' to "
+ "grok.local_utility." % factory, factory)
+ else:
+ provides = list(interface.implementedBy(factory))
+
+ util.check_implements_one_from_list(provides, factory)
+ provides = provides[0]
+
+ if (provides, name) in self.frame.f_locals.get(self.dotted_name(), {}):
+ raise GrokImportError(
+ "Conflicting local utility registration %r. "
+ "Local utilities are registered multiple "
+ "times for interface %r and name %r." %
+ (factory, provides, name), factory)
+
+ info = LocalUtilityInfo(factory, provides, name, setup, public,
+ name_in_container)
+ return (provides, name), info
+
+
class LocalUtilityInfo(object):
- def __init__(self, factory, provides=None, name=u'',
+
+ _order = 0
+
+ def __init__(self, factory, provides, name=u'',
setup=None, public=False, name_in_container=None):
self.factory = factory
- if provides is None:
- provides = util.class_annotation(factory, 'grok.provides', None)
self.provides = provides
self.name = name
self.setup = setup
self.public = public
self.name_in_container = name_in_container
+ self.order = LocalUtilityInfo._order
+ LocalUtilityInfo._order += 1
-class MultipleTimesAsDictDirective(Directive):
- def store(self, frame, value):
- values = frame.f_locals.get(self.local_name, {})
- values[value[1]] = value[0]
- frame.f_locals[self.local_name] = values
+ def __cmp__(self, other):
+ # LocalUtilityInfos have an inherit sort order by which the
+ # registrations take place.
+ return cmp(self.order, other.order)
-class TraversableDirective(MultipleTimesAsDictDirective):
- def check_argument_signature(self, attr, name=None):
- pass
- def check_arguments(self, attr, name=None):
- pass
- def value_factory(self, attr, name=None):
- if name is None:
- name = attr
- return (attr, name)
+class RequireDirectiveStore(StoreMultipleTimes):
+ def get(self, directive, component, default):
+ permissions = getattr(component, directive.dotted_name(), default)
+ if (permissions is default) or not permissions:
+ return default
+ if len(permissions) > 1:
+ raise GrokError('grok.require was called multiple times in '
+ '%r. It may only be set once for a class.'
+ % component, component)
+ return permissions[0]
-class RequireDirective(SingleValue, MultipleTimesDirective):
- def check_arguments(self, value):
+ def pop(self, locals_, directive):
+ return locals_[directive.dotted_name()].pop()
+
+class require(martian.Directive):
+ scope = martian.CLASS
+ store = RequireDirectiveStore()
+
+ def validate(self, value):
if util.check_subclass(value, components.Permission):
return
if util.not_unicode_or_ascii(value):
raise GrokImportError(
"You can only pass unicode, ASCII, or a subclass "
- "of grok.Permission %s." % self.name)
+ "of grok.Permission to the '%s' directive." % self.name)
- def store(self, frame, value):
+ def factory(self, value):
if util.check_subclass(value, components.Permission):
- value = getattr(value, '__grok_name__')
+ return grok.name.get(value)
+ return value
- super(RequireDirective, self).store(frame, value)
- values = frame.f_locals.get(self.local_name, [])
-
+ def __call__(self, func):
# grok.require can be used both as a class-level directive and
# as a decorator for methods. Therefore we return a decorator
# here, which may be used for methods, or simply ignored when
# used as a directive.
- def decorator(func):
- permission = values.pop()
- func.__grok_require__ = permission
- return func
- return decorator
+ frame = sys._getframe(1)
+ permission = self.store.pop(frame.f_locals, self)
+ self.set(func, [permission])
+ return func
+class site(martian.Directive):
+ scope = martian.CLASS
+ store = martian.ONCE
+ validate = martian.validateInterfaceOrClass
-# Define grok directives
-template = SingleTextDirective('grok.template', ClassDirectiveContext())
-templatedir = SingleTextDirective('grok.templatedir', ModuleDirectiveContext())
-local_utility = LocalUtilityDirective('grok.local_utility',
- ClassDirectiveContext())
-require = RequireDirective('grok.require', ClassDirectiveContext())
-site = InterfaceOrClassDirective('grok.site',
- ClassDirectiveContext())
-permissions = MultiValueOnceDirective(
- 'grok.permissions', ClassDirectiveContext())
-layer = InterfaceOrClassDirective('grok.layer',
- ClassOrModuleDirectiveContext())
-viewletmanager = InterfaceOrClassDirective('grok.viewletmanager',
- ClassOrModuleDirectiveContext())
-view = InterfaceOrClassDirective('grok.view',
- ClassOrModuleDirectiveContext())
-traversable = TraversableDirective('grok.traversable', ClassDirectiveContext())
+class permissions(martian.Directive):
+ scope = martian.CLASS
+ store = martian.ONCE
+ default = []
+
+ def factory(*args):
+ return args
+
+class OneInterfaceOrClassOnClassOrModule(martian.Directive):
+ """Convenience base class. Not for public use."""
+ scope = martian.CLASS_OR_MODULE
+ store = martian.ONCE
+ validate = martian.validateInterfaceOrClass
+
+class layer(OneInterfaceOrClassOnClassOrModule):
+ pass
+
+class viewletmanager(OneInterfaceOrClassOnClassOrModule):
+ pass
+
+class view(OneInterfaceOrClassOnClassOrModule):
+ default = IBrowserView
+
+class traversable(martian.Directive):
+ scope = martian.CLASS
+ store = martian.DICT
+
+ def factory(self, attr, name=None):
+ if name is None:
+ name = attr
+ return (name, attr)
+
+class order(martian.Directive):
+ scope = martian.CLASS
+ store = martian.ONCE
+ default = 0, 0
+
+ _order = 0
+
+ def factory(self, value=0):
+ order._order += 1
+ return value, order._order
Modified: grok/trunk/src/grok/ftests/catalog/indexes_multiple_conflict.py
===================================================================
--- grok/trunk/src/grok/ftests/catalog/indexes_multiple_conflict.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/ftests/catalog/indexes_multiple_conflict.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -12,7 +12,7 @@
...
GrokError: grok.Indexes in module <module
'grok.ftests.catalog.indexes_multiple_conflict' from ...>
- causes creation of catalog index 'name' in catalog '', but an index
+ causes creation of catalog index 'name' in catalog u'', but an index
with that name is already present.
>>> from zope.app.component.hooks import setSite
Deleted: grok/trunk/src/grok/ftests/grok_component.txt
===================================================================
--- grok/trunk/src/grok/ftests/grok_component.txt 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/ftests/grok_component.txt 2008-05-04 15:27:37 UTC (rev 86390)
@@ -1,41 +0,0 @@
-Test grok_component() in an ordinary doctest.
-
-We already have tests for grok_component(), but these were placed
-inside a module. We will now test grok_component() in a pure doctest
-context. This used to demonstrate an error in martian when dealing
-with the __builtin__ module (fixed in martian 0.9.2).
-
-grok.testing.grok_component() can be used to grok individual
-components within a doctest, such as adapters. It sets up just enough
-context for some grokking to work, though more complicated grokkers
-which need module context (such as view grokkers) might not work.
-
-This defines the object we want to provide an adapter for::
-
- >>> class Bar(object):
- ... pass
-
-This is the interface that we want to adapt to::
-
- >>> from zope.interface import Interface
- >>> class IFoo(Interface):
- ... pass
-
-This is the adapter itself::
-
- >>> import grok
- >>> class MyAdapter(grok.Adapter):
- ... grok.provides(IFoo)
- ... grok.context(Bar)
-
-Now we will register the adapter using grok_component()::
-
- >>> from grok.testing import grok_component
- >>> grok_component('MyAdapter', MyAdapter)
- True
-
-The adapter should now be available::
-
- >>> adapted = IFoo(Bar())
- >>> isinstance(adapted, MyAdapter)
- True
Modified: grok/trunk/src/grok/ftests/test_grok_functional.py
===================================================================
--- grok/trunk/src/grok/ftests/test_grok_functional.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/ftests/test_grok_functional.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -73,13 +73,6 @@
'security', 'utility', 'catalog', 'admin', 'site', 'rest',
'viewlet']:
suite.addTest(suiteFromPackage(name))
-
- # this test cannot follow the normal testing pattern, as the
- # bug it tests for is only exposed in the context of a doctest
- grok_component = doctest.DocFileSuite('grok_component.txt')
- grok_component.layer = GrokFunctionalLayer
- suite.addTest(grok_component)
-
return suite
if __name__ == '__main__':
Modified: grok/trunk/src/grok/ftests/utility/local.py
===================================================================
--- grok/trunk/src/grok/ftests/utility/local.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/ftests/utility/local.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -8,13 +8,13 @@
>>> from zope import component
>>> from zope.app.component.hooks import getSite, setSite
>>> setSite(cave)
-
+
>>> fireplace = component.getUtility(IFireplace)
>>> IFireplace.providedBy(fireplace)
True
>>> isinstance(fireplace, Fireplace)
True
-
+
>>> club = component.getUtility(IClub)
>>> IClub.providedBy(club)
True
Modified: grok/trunk/src/grok/meta.py
===================================================================
--- grok/trunk/src/grok/meta.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/meta.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -17,7 +17,6 @@
import zope.component.interface
from zope import interface, component
-from zope.publisher.browser import IBrowserView
from zope.publisher.interfaces.browser import (IDefaultBrowserLayer,
IBrowserRequest,
IBrowserPublisher,
@@ -50,43 +49,36 @@
import grok
from grok import components, formlib, templatereg
-from grok.util import check_permission, get_default_permission, make_checker
+from grok.util import check_permission, make_checker
from grok.util import public_methods_from_class
+from grok.util import get_name_classname
from grok.rest import RestPublisher
from grok.interfaces import IRESTSkinType
from grok.interfaces import IViewletManager as IGrokViewletManager
-from grokcore.component.meta import get_context, get_name, get_name_classname
-from grokcore.component.util import check_adapts
-from grokcore.component.util import determine_class_component
-from grokcore.component.util import determine_class_directive
-from grokcore.component.util import determine_module_component
+from grokcore.component.scan import determine_module_component
+from grokcore.component.scan import check_module_component
-def get_viewletmanager(module_info, factory):
- return determine_class_component(module_info, factory,
- 'viewletmanager', 'grok.viewletmanager')
-
class ViewletManagerContextGrokker(martian.GlobalGrokker):
priority = 1001
def grok(self, name, module, module_info, config, **kw):
viewletmanager = determine_module_component(module_info,
- 'grok.viewletmanager',
+ grok.viewletmanager,
IGrokViewletManager)
- module.__grok_viewletmanager__ = viewletmanager
+ grok.viewletmanager.set(module, viewletmanager)
return True
class XMLRPCGrokker(martian.ClassGrokker):
component_class = grok.XMLRPC
def grok(self, name, factory, module_info, config, **kw):
- view_context = get_context(module_info, factory)
+ view_context = grok.context.get(factory, module_info.getModule())
methods = public_methods_from_class(factory)
+ default_permission = grok.require.get(factory)
- default_permission = get_default_permission(factory)
-
# make sure we issue an action to check whether this permission
# exists. That's the only thing that action does
if default_permission is not None:
@@ -116,8 +108,9 @@
# Protect method_view with either the permission that was
# set on the method, the default permission from the class
# level or zope.Public.
- permission = getattr(method, '__grok_require__',
- default_permission)
+ permission = grok.require.get(method)
+ if permission is None:
+ permission = default_permission
config.action(
discriminator=('protectName', method_view, '__call__'),
@@ -130,11 +123,10 @@
component_class = grok.REST
def grok(self, name, factory, module_info, config, **kw):
- view_context = get_context(module_info, factory)
+ view_context = grok.context.get(factory, module_info.getModule())
methods = public_methods_from_class(factory)
-
- default_permission = get_default_permission(factory)
+ default_permission = grok.require.get(factory)
# make sure we issue an action to check whether this permission
# exists. That's the only thing that action does
if default_permission is not None:
@@ -145,9 +137,9 @@
)
# grab layer from class or module
- view_layer = determine_class_directive('grok.layer', factory,
- module_info,
- default=grok.IRESTLayer)
+ view_layer = grok.layer.get(factory, module_info.getModule())
+ if view_layer is None:
+ view_layer = grok.IRESTLayer
for method in methods:
name = method.__name__
@@ -169,8 +161,10 @@
# Protect method_view with either the permission that was
# set on the method, the default permission from the class
# level or zope.Public.
- permission = getattr(method, '__grok_require__',
- default_permission)
+ permission = grok.require.get(method)
+ if permission is None:
+ permission = default_permission
+
config.action(
discriminator=('protectName', method_view, '__call__'),
callable=make_checker,
@@ -183,7 +177,7 @@
component_class = grok.View
def grok(self, name, factory, module_info, config, **kw):
- view_context = get_context(module_info, factory)
+ view_context = grok.context.get(factory, module_info.getModule())
factory.module_info = module_info
@@ -212,16 +206,16 @@
# @grok.require on any of the view's methods.
methods = util.methods_from_class(factory)
for method in methods:
- if getattr(method, '__grok_require__', None) is not None:
+ if grok.require.get(method) is not None:
raise GrokError('The @grok.require decorator is used for '
'method %r in view %r. It may only be used '
'for XML-RPC methods.'
% (method.__name__, factory), factory)
# grab layer from class or module
- view_layer = determine_class_directive('grok.layer',
- factory, module_info,
- default=IDefaultBrowserLayer)
+ view_layer = grok.layer.get(factory, module_info.getModule())
+ if view_layer is None:
+ view_layer = IDefaultBrowserLayer
view_name = get_name_classname(factory)
# __view_name__ is needed to support IAbsoluteURL on views
@@ -234,7 +228,7 @@
args=(factory, adapts, interface.Interface, view_name),
)
- permission = get_default_permission(factory)
+ permission = grok.require.get(factory)
config.action(
discriminator=('protectName', factory, '__call__'),
callable=make_checker,
@@ -257,11 +251,10 @@
component_class = grok.JSON
def grok(self, name, factory, module_info, config, **kw):
- view_context = get_context(module_info, factory)
+ view_context = grok.context.get(factory, module_info.getModule())
methods = public_methods_from_class(factory)
-
- default_permission = get_default_permission(factory)
+ default_permission = grok.require.get(factory)
# make sure we issue an action to check whether this permission
# exists. That's the only thing that action does
if default_permission is not None:
@@ -298,8 +291,9 @@
# set on the method, the default permission from the class
# level or zope.Public.
- permission = getattr(method, '__grok_require__',
- default_permission)
+ permission = grok.require.get(method)
+ if permission is None:
+ permission = default_permission
config.action(
discriminator=('protectName', method_view, '__call__'),
@@ -313,7 +307,7 @@
component_class = grok.Traverser
def grok(self, name, factory, module_info, config, **kw):
- factory_context = get_context(module_info, factory)
+ factory_context = grok.context.get(factory, module_info.getModule())
adapts = (factory_context, IHTTPRequest)
config.action(
@@ -433,69 +427,22 @@
priority = 500
def grok(self, name, factory, module_info, config, **kw):
- infos = util.class_annotation_list(factory, 'grok.local_utility', None)
- if infos is None:
+ infos = grok.local_utility.get(factory)
+ if not infos:
return False
+ infos = infos.values()
for info in infos:
if info.public and not IContainer.implementedBy(factory):
raise GrokError(
"Cannot set public to True with grok.local_utility as "
"the site (%r) is not a container." %
factory, factory)
- if info.provides is None:
- if util.check_subclass(info.factory, grok.LocalUtility):
- baseInterfaces = interface.implementedBy(grok.LocalUtility)
- utilityInterfaces = interface.implementedBy(info.factory)
- provides = list(utilityInterfaces - baseInterfaces)
- if len(provides) == 0 and len(list(utilityInterfaces)) > 0:
- raise GrokError(
- "Cannot determine which interface to use "
- "for utility registration of %r in site %r. "
- "It implements an interface that is a specialization "
- "of an interface implemented by grok.LocalUtility. "
- "Specify the interface by either using grok.provides "
- "on the utility or passing 'provides' to "
- "grok.local_utility." % (info.factory, factory),
- info.factory)
- else:
- provides = list(interface.implementedBy(info.factory))
-
- util.check_implements_one_from_list(provides, info.factory)
- info.provides = provides[0]
-
- # raise an error in case of any duplicate registrations
- # on the class level (subclassing overrides, see below)
- used = set()
- class_infos = util.class_annotation(factory, 'grok.local_utility',
- [])
- for info in class_infos:
- key = (info.provides, info.name)
- if key in used:
- raise GrokError(
- "Conflicting local utility registration %r in "
- "site %r. Local utilities are registered multiple "
- "times for interface %r and name %r." %
- (info.factory, factory, info.provides, info.name),
- factory)
- used.add(key)
-
- # Make sure that local utilities from subclasses override
- # utilities from base classes if the registration (provided
- # interface, name) is identical.
- overridden_infos = []
- used = set()
- for info in reversed(infos):
- key = (info.provides, info.name)
- if key in used:
- continue
- used.add(key)
- overridden_infos.append(info)
- overridden_infos.reverse()
-
- # store infos on site class
- factory.__grok_utilities_to_install__ = overridden_infos
+ # Store the list of info objects in their "natural" order on the
+ # site class. They will be picked up by a subscriber doing the
+ # actual registrations in definition order.
+ factory.__grok_utilities_to_install__ = sorted(infos)
adapts = (factory, grok.IObjectAddedEvent)
config.action(
@@ -513,8 +460,7 @@
if installed:
return
- for info in util.class_annotation(site.__class__,
- 'grok.utilities_to_install', []):
+ for info in getattr(site.__class__, '__grok_utilities_to_install__', []):
setupUtility(site, info.factory(), info.provides, name=info.name,
name_in_container=info.name_in_container,
public=info.public, setup=info.setup)
@@ -565,18 +511,19 @@
priority = 1500
def grok(self, name, factory, module_info, config, **kw):
- id = get_name(factory, None)
- if id is None:
+ id = grok.name.get(factory)
+ if not id:
raise GrokError(
"A permission needs to have a dotted name for its id. Use "
"grok.name to specify one.", factory)
# We can safely convert to unicode, since the directives make sure
# it is either unicode already or ASCII.
id = unicode(id)
- permission = factory(
- id,
- unicode(util.class_annotation(factory, 'grok.title', id)),
- unicode(util.class_annotation(factory, 'grok.description', '')))
+ title = grok.title.get(factory)
+ if not title:
+ title = id
+ permission = factory(id, unicode(title),
+ unicode(grok.description.get(factory)))
config.action(
discriminator=('utility', IPermission, id),
@@ -591,18 +538,19 @@
priority = PermissionGrokker.priority - 1
def grok(self, name, factory, module_info, config, **kw):
- id = get_name(factory, None)
- if id is None:
+ id = grok.name.get(factory)
+ if not id:
raise GrokError(
"A role needs to have a dotted name for its id. Use "
"grok.name to specify one.", factory)
# We can safely convert to unicode, since the directives makes sure
# it is either unicode already or ASCII.
id = unicode(id)
- role = factory(
- id,
- unicode(util.class_annotation(factory, 'grok.title', id)),
- unicode(util.class_annotation(factory, 'grok.description', '')))
+ title = grok.title.get(factory)
+ if not title:
+ title = id
+ role = factory(id, unicode(title),
+ unicode(grok.description.get(factory)))
config.action(
discriminator=('utility', IRole, id),
@@ -610,7 +558,7 @@
args=(role, IRole, id),
)
- permissions = util.class_annotation(factory, 'grok.permissions', ())
+ permissions = grok.permissions.get(factory)
for permission in permissions:
config.action(
discriminator=('grantPermissionToRole', permission, id),
@@ -623,10 +571,8 @@
component_class = grok.Annotation
def grok(self, name, factory, module_info, config, **kw):
- adapter_context = get_context(module_info, factory)
- # XXX cannot use get_provides here, can we refactor others to reuse
- # this bit?
- provides = util.class_annotation(factory, 'grok.provides', None)
+ adapter_context = grok.context.get(factory, module_info.getModule())
+ provides = grok.provides.get(factory)
if provides is None:
base_interfaces = interface.implementedBy(grok.Annotation)
factory_interfaces = interface.implementedBy(factory)
@@ -634,8 +580,8 @@
util.check_implements_one_from_list(real_interfaces, factory)
provides = real_interfaces[0]
- key = get_name(factory, None)
- if key is None:
+ key = grok.name.get(factory)
+ if not key:
key = factory.__module__ + '.' + factory.__name__
@component.adapter(adapter_context)
@@ -683,17 +629,17 @@
component_class = components.IndexesClass
def grok(self, name, factory, module_info, config, **kw):
- site = util.class_annotation(factory, 'grok.site', None)
+ site = grok.site.get(factory)
if site is None:
raise GrokError("No site specified for grok.Indexes "
"subclass in module %r. "
"Use grok.site() to specify." % module_info.getModule(),
factory)
- indexes = util.class_annotation(factory, 'grok.indexes', None)
+ indexes = getattr(factory, '__grok_indexes__', None)
if indexes is None:
return False
- context = get_context(module_info, factory)
- catalog_name = get_name(factory)
+ context = grok.context.get(factory, module_info.getModule())
+ catalog_name = grok.name.get(factory)
subscriber = IndexesSetupSubscriber(catalog_name, indexes,
context, module_info)
@@ -761,8 +707,10 @@
component_class = grok.Skin
def grok(self, name, factory, module_info, config, **kw):
- layer = determine_class_directive('grok.layer', factory, module_info,
- default=IBrowserRequest)
+ layer = grok.layer.get(factory, module_info.getModule())
+ if layer is None:
+ layer = IBrowserRequest
+
name = get_name_classname(factory)
config.action(
discriminator=('skin', name),
@@ -775,8 +723,10 @@
component_class = grok.RESTProtocol
def grok(self, name, factory, module_info, config, **kw):
- layer = determine_class_directive('grok.layer', factory, module_info,
- default=IBrowserRequest)
+ layer = grok.layer.get(factory, module_info.getModule())
+ if layer is None:
+ layer = IBrowserRequest
+
name = get_name_classname(factory)
config.action(
discriminator=('restprotocol', name),
@@ -800,14 +750,13 @@
args=(templates, module_info, factory)
)
- name = get_name(factory)
- view_context = get_context(module_info, factory)
+ name = grok.name.get(factory)
+ view_context = grok.context.get(factory, module_info.getModule())
+ view = grok.view.get(factory, module_info.getModule())
- view = determine_class_directive('grok.view', factory,
- module_info, default=IBrowserView)
- viewlet_layer = determine_class_directive('grok.layer', factory,
- module_info,
- default=IDefaultBrowserLayer)
+ viewlet_layer = grok.layer.get(factory, module_info.getModule())
+ if viewlet_layer is None:
+ viewlet_layer = IDefaultBrowserLayer
config.action(
discriminator = ('viewletManager', view_context, viewlet_layer,
@@ -833,7 +782,7 @@
def grok(self, name, factory, module_info, config, **kw):
viewlet_name = get_name_classname(factory)
- viewlet_context = get_context(module_info, factory)
+ viewlet_context = grok.context.get(factory, module_info.getModule())
factory.module_info = module_info # to make /static available
@@ -846,13 +795,16 @@
args=(templates, module_info, factory)
)
- view = determine_class_directive('grok.view', factory,
- module_info, default=IBrowserView)
- viewlet_layer = determine_class_directive('grok.layer', factory,
- module_info,
- default=IDefaultBrowserLayer)
- viewletmanager = get_viewletmanager(module_info, factory)
+ view = grok.view.get(factory, module_info.getModule())
+ viewlet_layer = grok.layer.get(factory, module_info.getModule())
+ if viewlet_layer is None:
+ viewlet_layer = IDefaultBrowserLayer
+ viewletmanager = grok.viewletmanager.get(factory,
+ module_info.getModule())
+ check_module_component(
+ factory, viewletmanager, 'viewletmanager', grok.viewletmanager)
+
config.action(
discriminator = ('viewlet', viewlet_context, viewlet_layer,
view, viewletmanager, viewlet_name),
@@ -861,7 +813,7 @@
viewletmanager), IViewlet, viewlet_name)
)
- permission = get_default_permission(factory)
+ permission = grok.require.get(factory)
config.action(
discriminator=('protectName', factory, '__call__'),
callable=make_checker,
Modified: grok/trunk/src/grok/templatereg.py
===================================================================
--- grok/trunk/src/grok/templatereg.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/templatereg.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -24,8 +24,9 @@
return entry['template']
def findFilesystem(self, module_info):
- template_dir_name = module_info.getAnnotation(
- 'grok.templatedir', module_info.name + '_templates')
+ template_dir_name = grok.templatedir.get(module_info.getModule())
+ if template_dir_name is None:
+ template_dir_name = module_info.name + '_templates'
template_dir = module_info.getResourcePath(template_dir_name)
@@ -87,8 +88,9 @@
def checkTemplates(self, module_info, factory, component_name,
has_render, has_no_render):
factory_name = factory.__name__.lower()
- template_name = util.class_annotation(factory, 'grok.template',
- factory_name)
+ template_name = grok.template.get(factory)
+ if template_name is None:
+ template_name = factory_name
if factory_name != template_name:
# grok.template is being used
Modified: grok/trunk/src/grok/testing.py
===================================================================
--- grok/trunk/src/grok/testing.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/testing.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -13,11 +13,13 @@
##############################################################################
"""Grok test helpers
"""
+import os.path
+import z3c.testsetup
+import grokcore.component
from zope.configuration.config import ConfigurationMachine
from martian import scan
from grokcore.component import zcml
-import z3c.testsetup
-import os.path
+from grokcore.component.testing import grok_component
class GrokTestCollector(z3c.testsetup.TestCollector):
@@ -44,23 +46,3 @@
zcml.do_grok('grok.templatereg', config)
zcml.do_grok(module_name, config)
config.execute_actions()
-
-def grok_component(name, component,
- context=None, module_info=None, templates=None):
- if module_info is None:
- obj_module = getattr(component, '__grok_module__', None)
- if obj_module is None:
- obj_module = getattr(component, '__module__', None)
- module_info = scan.module_info_from_dotted_name(obj_module)
-
- module = module_info.getModule()
- if context is not None:
- module.__grok_context__ = context
- if templates is not None:
- module.__grok_templates__ = templates
- config = ConfigurationMachine()
- result = zcml.the_multi_grokker.grok(name, component,
- module_info=module_info,
- config=config)
- config.execute_actions()
- return result
Modified: grok/trunk/src/grok/tests/adapter/classcontextmultiple.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/classcontextmultiple.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/adapter/classcontextmultiple.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -4,7 +4,8 @@
>>> import grok.tests.adapter.classcontextmultiple_fixture
Traceback (most recent call last):
...
- GrokImportError: grok.context can only be called once per class or module.
+ GrokImportError: The 'context' directive can only be called once per
+ class or module.
"""
Modified: grok/trunk/src/grok/tests/adapter/classorinterface.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/classorinterface.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/adapter/classorinterface.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,22 +5,22 @@
>>> function_context()
Traceback (most recent call last):
...
- GrokImportError: You can only pass classes or interfaces to grok.context.
+ GrokImportError: The 'context' directive can only be called with a class or an interface.
>>> string_context()
Traceback (most recent call last):
...
- GrokImportError: You can only pass classes or interfaces to grok.context.
+ GrokImportError: The 'context' directive can only be called with a class or an interface.
>>> module_context()
Traceback (most recent call last):
...
- GrokImportError: You can only pass classes or interfaces to grok.context.
+ GrokImportError: The 'context' directive can only be called with a class or an interface.
>>> instance_context()
Traceback (most recent call last):
...
- GrokImportError: You can only pass classes or interfaces to grok.context.
+ GrokImportError: The 'context' directive can only be called with a class or an interface.
"""
import grok
Modified: grok/trunk/src/grok/tests/adapter/functioncontext.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/functioncontext.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/adapter/functioncontext.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -4,14 +4,16 @@
>>> func()
Traceback (most recent call last):
...
- GrokImportError: grok.context can only be used on class or module level.
+ GrokImportError: The 'context' directive can only be used on class or
+ module level.
You can't call grok.context from a method either:
>>> SomeClass().meth()
Traceback (most recent call last):
...
- GrokImportError: grok.context can only be used on class or module level.
+ GrokImportError: The 'context' directive can only be used on class or
+ module level.
"""
import grok
Modified: grok/trunk/src/grok/tests/adapter/importedmodel2.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/importedmodel2.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/adapter/importedmodel2.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,7 +5,8 @@
Traceback (most recent call last):
...
GrokError: No module-level context for
- <class 'grok.tests.adapter.importedmodel2.Painting'>, please use grok.context.
+ <class 'grok.tests.adapter.importedmodel2.Painting'>,
+ please use the 'context' directive.
"""
import grok
Modified: grok/trunk/src/grok/tests/adapter/modulecontextmultiple.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/modulecontextmultiple.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/adapter/modulecontextmultiple.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -4,6 +4,7 @@
>>> import grok.tests.adapter.modulecontextmultiple_fixture
Traceback (most recent call last):
...
- GrokImportError: grok.context can only be called once per class or module.
+ GrokImportError: The 'context' directive can only be called once per
+ class or module.
"""
Modified: grok/trunk/src/grok/tests/adapter/multiadaptsnone.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/multiadaptsnone.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/adapter/multiadaptsnone.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,7 +5,7 @@
Traceback (most recent call last):
...
GrokError: <class 'grok.tests.adapter.multiadaptsnone.Home'> must specify
- which contexts it adapts (use grok.adapts to specify).
+ which contexts it adapts (use the 'adapts' directive to specify).
"""
import grok
Modified: grok/trunk/src/grok/tests/adapter/multiple.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/multiple.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/adapter/multiple.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,7 +5,8 @@
Traceback (most recent call last):
...
GrokError: Multiple possible contexts for
- <class 'grok.tests.adapter.multiple.Home'>, please use grok.context.
+ <class 'grok.tests.adapter.multiple.Home'>, please use the
+ 'context' directive.
"""
import grok
Modified: grok/trunk/src/grok/tests/adapter/nomodel.py
===================================================================
--- grok/trunk/src/grok/tests/adapter/nomodel.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/adapter/nomodel.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,7 +5,7 @@
Traceback (most recent call last):
...
GrokError: No module-level context for
- <class 'grok.tests.adapter.nomodel.Home'>, please use grok.context.
+ <class 'grok.tests.adapter.nomodel.Home'>, please use the 'context' directive.
"""
import grok
Modified: grok/trunk/src/grok/tests/baseclass/base.py
===================================================================
--- grok/trunk/src/grok/tests/baseclass/base.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/baseclass/base.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -1,23 +1,13 @@
"""
-Base classes shouldn't be grokked.
+Base classes shouldn't be grokked. The way is to use the
+'grok.baseclass' directive on the class itself.
-One way to indicate that something is a base class is by postfixing the
-classname with 'Base'. Another way is to use the 'grok.baseclass' directive
-on the class itself.
-
>>> grok.testing.grok(__name__)
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> from zope import component
>>> model = ModelBase()
- >>> view = component.getMultiAdapter((model, request), name='viewbase')
- Traceback (most recent call last):
- ...
- ComponentLookupError: ((<grok.tests.baseclass.base.ModelBase object at 0x...>,
- <zope.publisher.browser.TestRequest instance ...>),
- <InterfaceClass zope.interface.Interface>,
- 'viewbase')
>>> view = component.getMultiAdapter((model, request), name='anotherview')
Traceback (most recent call last):
@@ -33,10 +23,6 @@
class ModelBase(grok.Model):
pass
-class ViewBase(grok.View):
- def render(self):
- return "hello world"
-
class AnotherView(grok.View):
grok.baseclass()
Deleted: grok/trunk/src/grok/tests/baseclass/basecontext.py
===================================================================
--- grok/trunk/src/grok/tests/baseclass/basecontext.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/baseclass/basecontext.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -1,34 +0,0 @@
-"""
-A base class of something that can be a context (such as a model) can
-function as a module-level context, and thus can have views associated
-with it.
-
- >>> grok.testing.grok(__name__)
-
- >>> from zope.publisher.browser import TestRequest
- >>> request = TestRequest()
- >>> from zope import component
- >>> model = ModelBase()
- >>> view = component.getMultiAdapter((model, request), name='viewbase')
- Traceback (most recent call last):
- ...
- ComponentLookupError: ((<grok.tests.baseclass.basecontext.ModelBase object at 0x...>,
- <zope.publisher.browser.TestRequest instance ...>),
- <InterfaceClass zope.interface.Interface>,
- 'viewbase')
- >>> view = component.getMultiAdapter((model, request), name='realview')
- >>> view.render()
- 'hello world'
-"""
-
-import grok
-
-class ModelBase(grok.Model):
- pass
-
-class ViewBase(grok.View):
- def render(self):
- return "hello world"
-
-class RealView(ViewBase):
- pass
Modified: grok/trunk/src/grok/tests/directive/argumenterror.py
===================================================================
--- grok/trunk/src/grok/tests/directive/argumenterror.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/directive/argumenterror.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -2,5 +2,5 @@
>>> import grok.tests.directive.argumenterror_fixture
Traceback (most recent call last):
...
- TypeError: grok.templatedir takes exactly 1 argument (3 given)
+ TypeError: name takes exactly 1 argument (3 given)
"""
Modified: grok/trunk/src/grok/tests/directive/argumenterror_fixture.py
===================================================================
--- grok/trunk/src/grok/tests/directive/argumenterror_fixture.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/directive/argumenterror_fixture.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -1,3 +1,4 @@
import grok
-grok.templatedir('too', 'many', 'arguments')
+class Foo(object):
+ grok.name('too', 'many', 'arguments')
Modified: grok/trunk/src/grok/tests/directive/multipleasdict.py
===================================================================
--- grok/trunk/src/grok/tests/directive/multipleasdict.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/directive/multipleasdict.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -3,10 +3,8 @@
attributes can be mentioned.
>>> from martian import scan
- >>> from grok.tests.directive import multipleasdict
- >>> module_info = scan.module_info_from_module(multipleasdict)
-
- >>> g = Club.__grok_traversable__
+ >>> import grok
+ >>> g = grok.traversable.get(Club)
>>> isinstance(g, dict)
True
>>> g['demo']
Modified: grok/trunk/src/grok/tests/directive/multipletimes.py
===================================================================
--- grok/trunk/src/grok/tests/directive/multipletimes.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/directive/multipletimes.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -2,10 +2,8 @@
Since grok.global_utility is a MultipleTimesDirective, there is a list of
GlobalUtilityInfo objects annotated on the module.
- >>> from martian import scan
>>> from grok.tests.directive import multipletimes
- >>> module_info = scan.module_info_from_module(multipletimes)
- >>> guis = module_info.getAnnotation('grok.global_utility', None)
+ >>> guis = grok.global_utility.get(multipletimes)
>>> guis
[<grokcore.component.directive.GlobalUtilityInfo object at 0x...>,
<grokcore.component.directive.GlobalUtilityInfo object at 0x...>]
Modified: grok/trunk/src/grok/tests/grokker/grokcomponent.py
===================================================================
--- grok/trunk/src/grok/tests/grokker/grokcomponent.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/grokker/grokcomponent.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -43,7 +43,7 @@
>>> grok.testing.grok_component('SecondAdapter', SecondAdapter)
Traceback (most recent call last):
...
- GrokError: No module-level context for <class 'grok.tests.grokker.grokcomponent.SecondAdapter'>, please use grok.context.
+ GrokError: No module-level context for <class 'grok.tests.grokker.grokcomponent.SecondAdapter'>, please use the 'context' directive.
So we need to supply the context ourselves::
Modified: grok/trunk/src/grok/tests/json/nocontext.py
===================================================================
--- grok/trunk/src/grok/tests/json/nocontext.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/json/nocontext.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -7,7 +7,8 @@
Traceback (most recent call last):
...
GrokError: No module-level context for
- <class 'grok.tests.json.nocontext.TestJSON'>, please use grok.context.
+ <class 'grok.tests.json.nocontext.TestJSON'>, please use the
+ 'context' directive.
"""
import grok
Copied: grok/trunk/src/grok/tests/order (from rev 86389, grok/branches/jw-philipp-using-ndir-directives/src/grok/tests/order)
Modified: grok/trunk/src/grok/tests/security/not_a_permissionclass.py
===================================================================
--- grok/trunk/src/grok/tests/security/not_a_permissionclass.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/security/not_a_permissionclass.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -15,7 +15,7 @@
Traceback (most recent call last):
...
GrokImportError: You can only pass unicode, ASCII, or a subclass of
- grok.Permission grok.require.
+ grok.Permission to the 'require' directive.
"""
Modified: grok/trunk/src/grok/tests/test_grok.py
===================================================================
--- grok/trunk/src/grok/tests/test_grok.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/test_grok.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -46,7 +46,7 @@
'zcml', 'static', 'utility', 'xmlrpc', 'json', 'container',
'traversal', 'form', 'grokker', 'directive', 'util',
'baseclass', 'annotation', 'application', 'template',
- 'viewlet', 'testsetup', 'conflict']:
+ 'viewlet', 'testsetup', 'conflict', 'order']:
suite.addTest(suiteFromPackage(name))
return suite
Deleted: grok/trunk/src/grok/tests/util/class_annotation.py
===================================================================
--- grok/trunk/src/grok/tests/util/class_annotation.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/util/class_annotation.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -1,28 +0,0 @@
-"""
- >>> util.class_annotation_list(B, 'grok.foo', None)
- [5, 7]
- >>> util.class_annotation_list(B2, 'grok.foo', None)
- [5]
- >>> util.class_annotation_list(C, 'grok.foo', None)
- [5, 7, 8]
- >>> util.class_annotation_list(C2, 'grok.foo', None)
- [5, 7, 9]
-
-"""
-import grok
-from martian import util
-
-class A(object):
- __grok_foo__ = [5]
-
-class B(A):
- __grok_foo__ = [7]
-
-class B2(A):
- pass
-
-class C(B, B2):
- __grok_foo__ = [8]
-
-class C2(B2, B):
- __grok_foo__ = [9]
Modified: grok/trunk/src/grok/tests/utility/local_implementsmany.py
===================================================================
--- grok/trunk/src/grok/tests/utility/local_implementsmany.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/utility/local_implementsmany.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,26 +5,11 @@
In this test, the utility implements more than one interface, so it cannot be
registered as a local utility.
- >>> grok.testing.grok(__name__)
+ >>> import grok.tests.utility.local_implementsmany_fixture
Traceback (most recent call last):
...
- GrokError: <class 'grok.tests.utility.local_implementsmany.Fireplace'>
+ GrokError: <class 'grok.tests.utility.local_implementsmany_fixture.Fireplace'>
is implementing more than one interface (use grok.provides to specify
which one to use).
"""
-
-import grok
-from zope import interface
-
-class IHome(interface.Interface):
- pass
-
-class IFireplace(interface.Interface):
- pass
-
-class Fireplace(object):
- interface.implements(IHome, IFireplace)
-
-class Cave(grok.Model, grok.Site):
- grok.local_utility(Fireplace)
Copied: grok/trunk/src/grok/tests/utility/local_implementsmany_fixture.py (from rev 86389, grok/branches/jw-philipp-using-ndir-directives/src/grok/tests/utility/local_implementsmany_fixture.py)
===================================================================
--- grok/trunk/src/grok/tests/utility/local_implementsmany_fixture.py (rev 0)
+++ grok/trunk/src/grok/tests/utility/local_implementsmany_fixture.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -0,0 +1,14 @@
+import grok
+from zope import interface
+
+class IHome(interface.Interface):
+ pass
+
+class IFireplace(interface.Interface):
+ pass
+
+class Fireplace(object):
+ interface.implements(IHome, IFireplace)
+
+class Cave(grok.Model, grok.Site):
+ grok.local_utility(Fireplace)
Modified: grok/trunk/src/grok/tests/utility/local_implementsnone.py
===================================================================
--- grok/trunk/src/grok/tests/utility/local_implementsnone.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/utility/local_implementsnone.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,19 +5,10 @@
In this test, the utility does not implement any interface, so it cannot be
registered as a local utility.
- >>> grok.testing.grok(__name__)
+ >>> import grok.tests.utility.local_implementsnone_fixture
Traceback (most recent call last):
...
- GrokError: <class 'grok.tests.utility.local_implementsnone.Fireplace'>
+ GrokError: <class 'grok.tests.utility.local_implementsnone_fixture.Fireplace'>
must implement at least one interface (use grok.implements to specify).
"""
-
-import grok
-from zope import interface
-
-class Fireplace(object):
- pass
-
-class Cave(grok.Model, grok.Site):
- grok.local_utility(Fireplace)
Modified: grok/trunk/src/grok/tests/utility/local_implementsnone2.py
===================================================================
--- grok/trunk/src/grok/tests/utility/local_implementsnone2.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/utility/local_implementsnone2.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -1,25 +1,14 @@
"""
- >>> grok.testing.grok(__name__)
+ >>> import grok.tests.utility.local_implementsnone2_fixture
Traceback (most recent call last):
...
- GrokError: Cannot determine which interface to use for utility registration of
- <class 'grok.tests.utility.local_implementsnone2.Fireplace'> in site
- <class 'grok.tests.utility.local_implementsnone2.Cave'>. It implements
- an interface that is a specialization of an interface implemented
- by grok.LocalUtility. Specify the interface by either using grok.provides on
- the utility or passing 'provides' to grok.local_utility.
+ GrokImportError: ("Cannot determine which interface to use for utility
+ registration of
+ <class 'grok.tests.utility.local_implementsnone2_fixture.Fireplace'>.
+ It implements an interface that is a specialization of an interface
+ implemented by grok.LocalUtility. Specify the interface by either
+ using grok.provides on the utility or passing 'provides' to
+ grok.local_utility.",
+ <class 'grok.tests.utility.local_implementsnone2_fixture.Fireplace'>)
"""
-
-import grok
-from zope import interface
-import persistent
-
-class ISpecialPersistent(persistent.interfaces.IPersistent):
- pass
-
-class Fireplace(grok.LocalUtility):
- grok.implements(ISpecialPersistent)
-
-class Cave(grok.Model, grok.Site):
- grok.local_utility(Fireplace)
Copied: grok/trunk/src/grok/tests/utility/local_implementsnone2_fixture.py (from rev 86389, grok/branches/jw-philipp-using-ndir-directives/src/grok/tests/utility/local_implementsnone2_fixture.py)
===================================================================
--- grok/trunk/src/grok/tests/utility/local_implementsnone2_fixture.py (rev 0)
+++ grok/trunk/src/grok/tests/utility/local_implementsnone2_fixture.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -0,0 +1,12 @@
+import grok
+from zope import interface
+import persistent
+
+class ISpecialPersistent(persistent.interfaces.IPersistent):
+ pass
+
+class Fireplace(grok.LocalUtility):
+ grok.implements(ISpecialPersistent)
+
+class Cave(grok.Model, grok.Site):
+ grok.local_utility(Fireplace)
Copied: grok/trunk/src/grok/tests/utility/local_implementsnone_fixture.py (from rev 86389, grok/branches/jw-philipp-using-ndir-directives/src/grok/tests/utility/local_implementsnone_fixture.py)
===================================================================
--- grok/trunk/src/grok/tests/utility/local_implementsnone_fixture.py (rev 0)
+++ grok/trunk/src/grok/tests/utility/local_implementsnone_fixture.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -0,0 +1,8 @@
+import grok
+from zope import interface
+
+class Fireplace(object):
+ pass
+
+class Cave(grok.Model, grok.Site):
+ grok.local_utility(Fireplace)
Modified: grok/trunk/src/grok/tests/utility/multiple_class.py
===================================================================
--- grok/trunk/src/grok/tests/utility/multiple_class.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/utility/multiple_class.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -2,28 +2,13 @@
When you try to register multiple classes with the same (interface, name)
combination multiple times using grok.local_utility, we expect an error:
- >>> grok.testing.grok(__name__)
+ >>> import grok.tests.utility.multiple_class_fixture
Traceback (most recent call last):
...
- GrokError: Conflicting local utility registration
- <class 'grok.tests.utility.multiple_class.Fireplace2'> in site
- <class 'grok.tests.utility.multiple_class.Cave'>.
+ GrokImportError: ("Conflicting local utility registration
+ <class 'grok.tests.utility.multiple_class_fixture.Fireplace2'>.
Local utilities are registered multiple times for interface
- <InterfaceClass grok.tests.utility.multiple_class.IFireplace> and
- name 'Foo'.
+ <InterfaceClass grok.tests.utility.multiple_class_fixture.IFireplace>
+ and name 'Foo'.",
+ <class 'grok.tests.utility.multiple_class_fixture.Fireplace2'>)
"""
-import grok
-from zope import interface
-
-class IFireplace(interface.Interface):
- pass
-
-class Fireplace(grok.LocalUtility):
- grok.implements(IFireplace)
-
-class Fireplace2(grok.LocalUtility):
- grok.implements(IFireplace)
-
-class Cave(grok.Model, grok.Site):
- grok.local_utility(Fireplace, name='Foo')
- grok.local_utility(Fireplace2, name='Foo')
Copied: grok/trunk/src/grok/tests/utility/multiple_class_fixture.py (from rev 86389, grok/branches/jw-philipp-using-ndir-directives/src/grok/tests/utility/multiple_class_fixture.py)
===================================================================
--- grok/trunk/src/grok/tests/utility/multiple_class_fixture.py (rev 0)
+++ grok/trunk/src/grok/tests/utility/multiple_class_fixture.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -0,0 +1,15 @@
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+ pass
+
+class Fireplace(grok.LocalUtility):
+ grok.implements(IFireplace)
+
+class Fireplace2(grok.LocalUtility):
+ grok.implements(IFireplace)
+
+class Cave(grok.Model, grok.Site):
+ grok.local_utility(Fireplace, name='Foo')
+ grok.local_utility(Fireplace2, name='Foo')
Modified: grok/trunk/src/grok/tests/utility/multiple_directive.py
===================================================================
--- grok/trunk/src/grok/tests/utility/multiple_directive.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/utility/multiple_directive.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -2,28 +2,13 @@
When you call the grok.local_utility directive multiple times specifying
the same (interface, name) combination, we expect an error:
- >>> grok.testing.grok(__name__)
+ >>> import grok.tests.utility.multiple_directive_fixture
Traceback (most recent call last):
...
- GrokError: Conflicting local utility registration
- <class 'grok.tests.utility.multiple_directive.Fireplace2'> in site
- <class 'grok.tests.utility.multiple_directive.Cave'>.
+ GrokImportError: ("Conflicting local utility registration
+ <class 'grok.tests.utility.multiple_directive_fixture.Fireplace2'>.
Local utilities are registered multiple times for interface
- <InterfaceClass grok.tests.utility.multiple_directive.IFireplace> and
- name u''.
+ <InterfaceClass grok.tests.utility.multiple_directive_fixture.IFireplace>
+ and name u''.",
+ <class 'grok.tests.utility.multiple_directive_fixture.Fireplace2'>)
"""
-import grok
-from zope import interface
-
-class IFireplace(interface.Interface):
- pass
-
-class Fireplace(grok.LocalUtility):
- grok.implements(IFireplace)
-
-class Fireplace2(grok.LocalUtility):
- grok.implements(IFireplace)
-
-class Cave(grok.Model, grok.Site):
- grok.local_utility(Fireplace, provides=IFireplace)
- grok.local_utility(Fireplace2, provides=IFireplace)
Copied: grok/trunk/src/grok/tests/utility/multiple_directive_fixture.py (from rev 86389, grok/branches/jw-philipp-using-ndir-directives/src/grok/tests/utility/multiple_directive_fixture.py)
===================================================================
--- grok/trunk/src/grok/tests/utility/multiple_directive_fixture.py (rev 0)
+++ grok/trunk/src/grok/tests/utility/multiple_directive_fixture.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -0,0 +1,15 @@
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+ pass
+
+class Fireplace(grok.LocalUtility):
+ grok.implements(IFireplace)
+
+class Fireplace2(grok.LocalUtility):
+ grok.implements(IFireplace)
+
+class Cave(grok.Model, grok.Site):
+ grok.local_utility(Fireplace, provides=IFireplace)
+ grok.local_utility(Fireplace2, provides=IFireplace)
Modified: grok/trunk/src/grok/tests/view/ambiguouscontext.py
===================================================================
--- grok/trunk/src/grok/tests/view/ambiguouscontext.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/view/ambiguouscontext.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,7 +5,8 @@
Traceback (most recent call last):
...
GrokError: Multiple possible contexts for
- <class 'grok.tests.view.ambiguouscontext.Club'>, please use grok.context.
+ <class 'grok.tests.view.ambiguouscontext.Club'>, please use the
+ 'context' directive.
"""
Modified: grok/trunk/src/grok/tests/view/missingcontext.py
===================================================================
--- grok/trunk/src/grok/tests/view/missingcontext.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/view/missingcontext.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,7 +5,8 @@
Traceback (most recent call last):
...
GrokError: No module-level context for
- <class 'grok.tests.view.missingcontext.Club'>, please use grok.context.
+ <class 'grok.tests.view.missingcontext.Club'>, please use the
+ 'context' directive.
"""
Modified: grok/trunk/src/grok/tests/view/namemultiple.py
===================================================================
--- grok/trunk/src/grok/tests/view/namemultiple.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/view/namemultiple.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -4,6 +4,6 @@
>>> import grok.tests.view.namemultiple_fixture
Traceback (most recent call last):
...
- GrokImportError: grok.name can only be called once per class.
+ GrokImportError: The 'name' directive can only be called once per class.
"""
Modified: grok/trunk/src/grok/tests/view/nameunicode.py
===================================================================
--- grok/trunk/src/grok/tests/view/nameunicode.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/view/nameunicode.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -6,11 +6,14 @@
>>> pass_encodedstring()
Traceback (most recent call last):
...
- GrokImportError: You can only pass unicode or ASCII to grok.name.
+ GrokImportError: The 'name' directive can only be called with
+ unicode or ASCII.
+
>>> pass_object()
Traceback (most recent call last):
...
- GrokImportError: You can only pass unicode or ASCII to grok.name.
+ GrokImportError: The 'name' directive can only be called with
+ unicode or ASCII.
"""
import grok
Modified: grok/trunk/src/grok/tests/view/nomodulename.py
===================================================================
--- grok/trunk/src/grok/tests/view/nomodulename.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/view/nomodulename.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -4,6 +4,6 @@
>>> import grok.tests.view.nomodulename_fixture
Traceback (most recent call last):
...
- GrokImportError: grok.name can only be used on class level.
+ GrokImportError: The 'name' directive can only be used on class level.
"""
Modified: grok/trunk/src/grok/tests/viewlet/viewlet_ambiguous_manager.py
===================================================================
--- grok/trunk/src/grok/tests/viewlet/viewlet_ambiguous_manager.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/viewlet/viewlet_ambiguous_manager.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,7 +5,7 @@
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
- GrokError: Multiple possible viewletmanagers for <class 'grok.tests.viewlet.viewlet_ambiguous_manager.Viewlet'>, please use grok.viewletmanager.
+ GrokError: Multiple possible viewletmanagers for <class 'grok.tests.viewlet.viewlet_ambiguous_manager.Viewlet'>, please use the 'viewletmanager' directive.
"""
Modified: grok/trunk/src/grok/tests/xmlrpc/nocontext.py
===================================================================
--- grok/trunk/src/grok/tests/xmlrpc/nocontext.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/xmlrpc/nocontext.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -7,7 +7,8 @@
Traceback (most recent call last):
...
GrokError: No module-level context for
- <class 'grok.tests.xmlrpc.nocontext.HomeRPC'>, please use grok.context.
+ <class 'grok.tests.xmlrpc.nocontext.HomeRPC'>, please use the
+ 'context' directive.
"""
import grok
Modified: grok/trunk/src/grok/tests/zcml/directiveerror.py
===================================================================
--- grok/trunk/src/grok/tests/zcml/directiveerror.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/zcml/directiveerror.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -15,7 +15,7 @@
Traceback (most recent call last):
...
ZopeXMLConfigurationError: File "<string>", line 6.4-6.57
- GrokError: No module-level context for <class 'grok.tests.zcml.directiveerror.CavePainting'>, please use grok.context.
+ GrokError: No module-level context for <class 'grok.tests.zcml.directiveerror.CavePainting'>, please use the 'context' directive.
"""
import grok
Modified: grok/trunk/src/grok/tests/zcml/directiveimporterror.py
===================================================================
--- grok/trunk/src/grok/tests/zcml/directiveimporterror.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/tests/zcml/directiveimporterror.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -15,5 +15,5 @@
Traceback (most recent call last):
...
ZopeXMLConfigurationError: File "...", line ...
- GrokImportError: grok.template can only be used on class level.
+ GrokImportError: The 'template' directive can only be used on class level.
"""
Modified: grok/trunk/src/grok/util.py
===================================================================
--- grok/trunk/src/grok/util.py 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/src/grok/util.py 2008-05-04 15:27:37 UTC (rev 86390)
@@ -16,6 +16,7 @@
import urllib
+import grok
import zope.location.location
from zope import component
from zope import interface
@@ -26,15 +27,13 @@
from zope.security.interfaces import IPermission
from martian.error import GrokError
-from martian.util import class_annotation, methods_from_class
+from martian.util import methods_from_class
-# BBB backwards-compatibility imports (in case somebody wrote custom
-# grokkers that use these utility functions)
-from grokcore.component.util import check_adapts
-from grokcore.component.util import determine_class_directive
-from grokcore.component.util import sort_components
-from grokcore.component.util import determine_module_component
-from grokcore.component.util import determine_class_component
+def get_name_classname(factory):
+ name = grok.name.get(factory)
+ if not name:
+ name = factory.__name__.lower()
+ return name
def public_methods_from_class(factory):
return [m for m in methods_from_class(factory) if \
@@ -67,22 +66,6 @@
'grok.Permission first.'
% (permission, factory), factory)
-def get_default_permission(factory):
- """Determine the default permission for a view.
-
- There can be only 0 or 1 default permission.
- """
- permissions = class_annotation(factory, 'grok.require', [])
- if not permissions:
- return None
- if len(permissions) > 1:
- raise GrokError('grok.require was called multiple times in '
- '%r. It may only be set once for a class.'
- % factory, factory)
-
- result = permissions[0]
- return result
-
def url(request, obj, name=None, data={}):
url = component.getMultiAdapter((obj, request), IAbsoluteURL)()
if name is not None:
@@ -118,3 +101,14 @@
# Add the new skin.
ifaces.append(skin)
interface.directlyProvides(request, *ifaces)
+
+def _sort_key(component):
+ explicit_order, implicit_order = grok.order.get(component)
+ return (explicit_order,
+ component.__module__,
+ implicit_order,
+ component.__class__.__name__)
+
+def sort_components(components):
+ # if components have a grok.order directive, sort by that
+ return sorted(components, key=_sort_key)
Modified: grok/trunk/versions.cfg
===================================================================
--- grok/trunk/versions.cfg 2008-05-04 15:19:30 UTC (rev 86389)
+++ grok/trunk/versions.cfg 2008-05-04 15:27:37 UTC (rev 86390)
@@ -5,8 +5,8 @@
ZConfig = 2.5.1
ZODB3 = 3.8
docutils = 0.4
-martian = 0.9.3
-grokcore.component = 1.1
+martian = 0.9.4
+grokcore.component = 1.2
mechanize = 0.1.7b
pytz = 2007k
simplejson = 1.7.1
More information about the Checkins
mailing list