[Checkins] SVN: grok/trunk/src/grok/ implemented grok.global_utility directive. There is no grokking yet, just the information gathering

Wolfgang Schnerring wosc at wosc.de
Sat Jan 6 11:39:19 EST 2007


Log message for revision 71743:
  implemented grok.global_utility directive. There is no grokking yet, just the information gathering

Changed:
  U   grok/trunk/src/grok/__init__.py
  U   grok/trunk/src/grok/directive.py
  A   grok/trunk/src/grok/tests/directive/multipletimes.py

-=-
Modified: grok/trunk/src/grok/__init__.py
===================================================================
--- grok/trunk/src/grok/__init__.py	2007-01-06 16:15:18 UTC (rev 71742)
+++ grok/trunk/src/grok/__init__.py	2007-01-06 16:39:19 UTC (rev 71743)
@@ -31,9 +31,11 @@
 
 from grok.components import ClassGrokker, InstanceGrokker, ModuleGrokker
 from grok.components import Model, Adapter, MultiAdapter, View, XMLRPC
-from grok.components import PageTemplate, GlobalUtility, Container, Traverser, Site
+from grok.components import PageTemplate, GlobalUtility, Container, Traverser
+from grok.components import Site
 from grok.components import EditForm, DisplayForm, AddForm
-from grok.directive import context, name, template, templatedir, provides
+from grok.directive import (context, name, template, templatedir, provides,
+                            global_utility)
 from grok._grok import do_grok as grok  # Avoid name clash within _grok
 from grok._grok import SubscribeDecorator as subscribe
 from grok.error import GrokError, GrokImportError

Modified: grok/trunk/src/grok/directive.py
===================================================================
--- grok/trunk/src/grok/directive.py	2007-01-06 16:15:18 UTC (rev 71742)
+++ grok/trunk/src/grok/directive.py	2007-01-06 16:39:19 UTC (rev 71743)
@@ -69,11 +69,10 @@
     ('.' in the name are replaced with '_').
     """
 
-    def __init__(self, name, directive_context, value_factory):
+    def __init__(self, name, directive_context):
         self.name = name
         self.local_name = '__%s__' % name.replace('.', '_')
         self.directive_context = directive_context
-        self.value_factory = value_factory
 
     def __call__(self, *args, **kw):
         self.check_argument_signature(*args, **kw)
@@ -107,6 +106,9 @@
                                   % (self.name,
                                      self.directive_context.description))
 
+    def value_factory(self, *args, **kw):
+        raise NotImplementedError
+
     def store(self, frame, value):
         raise NotImplementedError
 
@@ -118,7 +120,23 @@
                                      self.directive_context.description))
         frame.f_locals[self.local_name] = value
 
-class TextDirective(OnceDirective):
+class SingleValueOnceDirective(OnceDirective):
+    def check_arguments(self, value):
+        raise NotImplementedError
+
+    # Even though the value_factory is called with (*args, **kw), we're safe
+    # since check_arguments would have bailed out with a TypeError if the number
+    # arguments we were called with was not what we expect here.
+    def value_factory(self, value):
+        return value
+
+class MultipleTimesDirective(Directive):
+    def store(self, frame, value):
+        values = frame.f_locals.get(self.local_name, [])
+        values.append(value)
+        frame.f_locals[self.local_name] = values
+
+class TextDirective(SingleValueOnceDirective):
     """
     Directive that only accepts unicode/ASCII values.
     """
@@ -128,7 +146,7 @@
             raise GrokImportError("You can only pass unicode or ASCII to "
                                   "%s." % self.name)
 
-class InterfaceOrClassDirective(OnceDirective):
+class InterfaceOrClassDirective(SingleValueOnceDirective):
     """
     Directive that only accepts classes or interface values.
     """
@@ -138,7 +156,7 @@
             raise GrokImportError("You can only pass classes or interfaces to "
                                   "%s." % self.name)
 
-class InterfaceDirective(OnceDirective):
+class InterfaceDirective(SingleValueOnceDirective):
     """
     Directive that only accepts interface values.
     """
@@ -147,26 +165,28 @@
         if not (IInterface.providedBy(value)):
             raise GrokImportError("You can only pass interfaces to "
                                   "%s." % self.name)
-        
-# Even though the value_factory is called with (*args, **kw), we're safe since
-# check_arguments would have bailed out with a TypeError if the number arguments
-# we were called with was not what we expect here.
-def single_value_factory(value):
-    return value
 
+class GlobalUtilityDirective(MultipleTimesDirective):
+    def check_arguments(self, factory, 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)
+
+    def value_factory(self, *args, **kw):
+        return GlobalUtilityInfo(*args, **kw)
+
+class GlobalUtilityInfo(object):
+    def __init__(self, factory, provides=None, name=u''):
+        self.factory = factory
+        self.provides = provides
+        self.name = name
+
 # Define grok directives
-name = TextDirective('grok.name',
-                     ClassDirectiveContext(),
-                     single_value_factory)
-template = TextDirective('grok.template',
-                         ClassDirectiveContext(),
-                         single_value_factory)
+name = TextDirective('grok.name', ClassDirectiveContext())
+template = TextDirective('grok.template', ClassDirectiveContext())
 context = InterfaceOrClassDirective('grok.context',
-                                    ClassOrModuleDirectiveContext(),
-                                    single_value_factory)
-templatedir = TextDirective('grok.templatedir',
-                            ModuleDirectiveContext(),
-                            single_value_factory)
-provides = InterfaceDirective('grok.provides',
-                              ClassDirectiveContext(),
-                              single_value_factory)
+                                    ClassOrModuleDirectiveContext())
+templatedir = TextDirective('grok.templatedir', ModuleDirectiveContext())
+provides = InterfaceDirective('grok.provides', ClassDirectiveContext())
+global_utility = GlobalUtilityDirective('grok.global_utility',
+                                        ModuleDirectiveContext())

Added: grok/trunk/src/grok/tests/directive/multipletimes.py
===================================================================
--- grok/trunk/src/grok/tests/directive/multipletimes.py	2007-01-06 16:15:18 UTC (rev 71742)
+++ grok/trunk/src/grok/tests/directive/multipletimes.py	2007-01-06 16:39:19 UTC (rev 71743)
@@ -0,0 +1,42 @@
+"""
+Since grok.global_utility is a MultipleTimesDirective, there is a list of
+GlobalUtilityInfo objects annotated on the module.
+
+  >>> from grok 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.directive.GlobalUtilityInfo object at 0x...>,
+  <grok.directive.GlobalUtilityInfo object at 0x...>]
+  >>> guis[0].factory
+  <class 'grok.tests.directive.multipletimes.Club'>
+  >>> guis[0].provides
+  <InterfaceClass grok.tests.directive.multipletimes.IClub>
+  >>> guis[0].name
+  'foo'
+  >>> guis[1].factory
+  <class 'grok.tests.directive.multipletimes.Cave'>
+  >>> guis[1].provides is None
+  True
+  >>> guis[1].name
+  u''
+  
+"""
+import grok
+from zope import interface
+
+class IClub(interface.Interface):
+    pass
+
+class ICave(interface.Interface):
+    pass
+
+class Club(object):
+    grok.implements(IClub)
+
+class Cave(object):
+    grok.implements(ICave)
+
+grok.global_utility(Club, provides=IClub, name='foo')
+grok.global_utility(Cave)



More information about the Checkins mailing list