[Checkins] SVN: grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/ Use a more declarative way of specifying which directives a grokker wants to use

Philipp von Weitershausen philikon at philikon.de
Mon May 5 17:55:52 EDT 2008


Log message for revision 86472:
  Use a more declarative way of specifying which directives a grokker wants to use
  and automate the data retrieval in a base class.  Grokker implementations have now
  become much more concise, as many of the rules have been abstracted either into
  the directive implementations (which we already did) or into other default rules
  (which this patch is all about).
  
  This currently doesn't work anymore due to martian's new asserts on directive getters.
  A martian/branches/philikon-decl-dir-rules checkout with rev < 86447 is recommended
  for testing this.
  
  All tests but 1 pass :)
  

Changed:
  U   grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/directive.py
  U   grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/meta.py
  U   grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/scan.py
  U   grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/tests/directive/multipletimes.py

-=-
Modified: grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/directive.py
===================================================================
--- grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/directive.py	2008-05-05 21:28:40 UTC (rev 86471)
+++ grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/directive.py	2008-05-05 21:55:51 UTC (rev 86472)
@@ -28,24 +28,15 @@
             raise GrokImportError(
                 "You can only pass an interface to the "
                 "provides argument of %s." % self.name)
-        return GlobalUtilityInfo(factory, provides, name, direct)
 
-class GlobalUtilityInfo(object):
-
-    def __init__(self, factory, provides=None, name=u'', direct=None):
-        self.factory = factory
+        if provides is None:
+            provides = grokcore.component.provides.bind().get(factory)
         if direct is None:
-            direct = grokcore.component.direct.get(factory)
-        self.direct = direct
+            direct = grokcore.component.direct.bind().get(factory)
+        if not name:
+            name = grokcore.component.name.bind().get(factory)
+        return (factory, provides, name, direct)
 
-        if provides is None:
-            provides = grokcore.component.provides.get(factory)
-        self.provides = provides
-
-        if name is u'':
-            name = grokcore.component.name.get(factory)
-        self.name = name
-
 class name(martian.Directive):
     scope = martian.CLASS
     store = martian.ONCE
@@ -58,13 +49,11 @@
     validate = martian.validateInterfaceOrClass
 
     @classmethod
-    def get(cls, component, module=None):
-        value = super(cls, context).get(component, module)
+    def check_value(cls, value, component, module=None, **data):
         if not isinstance(component, types.ModuleType):
             # 'component' must be a class then, so let's make sure
             # that the context is not ambiguous or None.
             check_module_component(component, value, 'context', cls)    
-        return value
 
 class title(martian.Directive):
     scope = martian.CLASS

Modified: grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/meta.py
===================================================================
--- grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/meta.py	2008-05-05 21:28:40 UTC (rev 86471)
+++ grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/meta.py	2008-05-05 21:55:51 UTC (rev 86472)
@@ -24,15 +24,33 @@
 from grokcore.component.interfaces import IContext
 from grokcore.component.interfaces import IContext
 
-def get_provides(factory):
-    provides = grokcore.component.provides.get(factory)
 
-    if provides is None:
-        martian.util.check_implements_one(factory)
-        provides = list(interface.implementedBy(factory))[0]
-    return provides
+class ClassGrokker(martian.ClassGrokker):
 
+    def grok(self, name, class_, module_info, config, **kw):
+        module = module_info.getModule()
 
+        # Populate the data dict with information from the directives:
+        data = {}
+        for directive in self.directives:
+            data[directive.name] = directive.get(class_, module, **data)
+        return self.register(class_, config, **data)
+
+    def register(self, class_, config, **data):
+        raise NotImplementedError
+
+
+def default_provides(factory, module=None, **data):
+    martian.util.check_implements_one(factory)
+    return list(interface.implementedBy(factory))[0]
+
+def default_global_utility_provides(factory, module, direct, **data):
+    if direct:
+        martian.util.check_provides_one(factory)
+        return list(interface.providedBy(factory))[0]
+    return default_provides(factory)
+
+
 class ContextGrokker(martian.GlobalGrokker):
 
     priority = 1001
@@ -45,29 +63,33 @@
         return True
 
 
-class AdapterGrokker(martian.ClassGrokker):
+class AdapterGrokker(ClassGrokker):
     component_class = grokcore.component.Adapter
 
-    def grok(self, name, factory, module_info, config, **kw):
-        adapter_context = grokcore.component.context.get(factory, module_info.getModule())
-        provides = get_provides(factory)
-        name = grokcore.component.name.get(factory)
+    directives = [
+        grokcore.component.context.bind(),
+        grokcore.component.provides.bind(get_default=default_provides),
+        grokcore.component.name.bind(),
+        ]
 
+    def register(self, factory, config, context, provides, name):
         config.action(
-            discriminator=('adapter', adapter_context, provides, name),
+            discriminator=('adapter', context, provides, name),
             callable=component.provideAdapter,
-            args=(factory, (adapter_context,), provides, name),
+            args=(factory, (context,), provides, name),
             )
         return True
 
 
-class MultiAdapterGrokker(martian.ClassGrokker):
+class MultiAdapterGrokker(ClassGrokker):
     component_class = grokcore.component.MultiAdapter
 
-    def grok(self, name, factory, module_info, config, **kw):
-        provides = get_provides(factory)
-        name = grokcore.component.name.get(factory)
+    directives = [
+        grokcore.component.provides.bind(get_default=default_provides),
+        grokcore.component.name.bind(),
+        ]
 
+    def register(self, factory, config, provides, name):
         if component.adaptedBy(factory) is None:
             raise GrokError("%r must specify which contexts it adapts "
                             "(use the 'adapts' directive to specify)."
@@ -82,18 +104,7 @@
         return True
 
 
-def default_global_utility_provides(factory, module, direct, **data):
-    if direct:
-        if provides is None:
-            martian.util.check_provides_one(factory)
-            provides = list(interface.providedBy(factory))[0]
-    else:
-        if provides is None:
-            provides = get_provides(factory)
-    return provides
-
-
-class GlobalUtilityGrokker(martian.ClassGrokker):
+class GlobalUtilityGrokker(ClassGrokker):
     component_class = grokcore.component.GlobalUtility
 
     # This needs to happen before the FilesystemPageTemplateGrokker grokker
@@ -104,11 +115,9 @@
         grokcore.component.direct.bind(),
         grokcore.component.provides.bind(
             get_default=default_global_utility_provides),
-        grokcore.component.provides.bind(default=IFoo),
         grokcore.component.name.bind(),
         ]
 
-
     def register(self, factory, config, direct, provides, name):
         if not direct:
             factory = factory()
@@ -116,55 +125,14 @@
         config.action(
             discriminator=('utility', provides, name),
             callable=component.provideUtility,
-            args=(obj, provides, name),
+            args=(factory, provides, name),
             )
         return True
 
-
-    def grok(self, name, factory, module_info, config, **kw):
-        module = module_info.getModule()
-
-        # Populate the data dict with information from the directives:
-        data = {}
-        for bound_directive in self.directives:
-            data[dirname] = bound_directive.get(factory, module, **data)
-        return self.register(factory, config, **data)
-
-
-class Directive(...):
-
-    @classmethod
-    def bind(cls, default=None, get_default=None, name=None):
-        return BoundDirective(cls, default, get_default, name)
-
-
-class BoundDirective(object):
-
-    def __init__(self, directive, default=None, get_default=None, name=None):
-        self.directive = directive
-        self.default = default
-        if name is None:
-            name = directive.__name__
-        self.name = name
-        if get_default is not None:
-            self.get_default = get_default
-
-    def get_default(self, component, module, **data):
-        if self.default is not None:
-            return self.default
-        return self.directive.default
-
-    def get(self, component, module, **data):
-        value = self.directive.get(component, module, default=_DEFAULT)
-        if value is _DEFAULT:
-            value = self.get_default(component, module, **data)
-        return value
-
-
 class AdapterDecoratorGrokker(martian.GlobalGrokker):
 
     def grok(self, name, module, module_info, config, **kw):
-        context = grokcore.component.context.get(module)
+        context = grokcore.component.context.bind().get(module)
         implementers = module_info.getAnnotation('implementers', [])
         for function in implementers:
             interfaces = getattr(function, '__component_adapts__', None)
@@ -186,25 +154,23 @@
 class GlobalUtilityDirectiveGrokker(martian.GlobalGrokker):
 
     def grok(self, name, module, module_info, config, **kw):
-        infos = grokcore.component.global_utility.get(module)
+        infos = grokcore.component.global_utility.bind().get(module)
 
-        for info in infos:
-            provides = info.provides
-
-            if info.direct:
-                obj = info.factory
+        for factory, provides, name, direct in infos:
+            if direct:
+                obj = factory
                 if provides is None:
                     martian.util.check_provides_one(obj)
                     provides = list(interface.providedBy(obj))[0]
             else:
-                obj = info.factory()
+                obj = factory()
                 if provides is None:
-                    provides = get_provides(info.factory)
+                    provides = default_provides(factory)
 
             config.action(
-                discriminator=('utility', provides, info.name),
+                discriminator=('utility', provides, name),
                 callable=component.provideUtility,
-                args=(obj, provides, info.name),
+                args=(obj, provides, name),
                 )
 
         return True

Modified: grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/scan.py
===================================================================
--- grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/scan.py	2008-05-05 21:28:40 UTC (rev 86471)
+++ grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/scan.py	2008-05-05 21:55:51 UTC (rev 86472)
@@ -64,7 +64,7 @@
     else:
         component= AMBIGUOUS_COMPONENT
 
-    module_component = directive.get(module)
+    module_component = directive.bind().get(module)
     if module_component is not None:
         component = module_component
     return component

Modified: grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/tests/directive/multipletimes.py
===================================================================
--- grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/tests/directive/multipletimes.py	2008-05-05 21:28:40 UTC (rev 86471)
+++ grokcore.component/branches/philikon-decl-dir-rules/src/grokcore/component/tests/directive/multipletimes.py	2008-05-05 21:55:51 UTC (rev 86472)
@@ -6,21 +6,24 @@
   >>> from martian import scan
   >>> import grokcore.component as grok
   >>> from grokcore.component.tests.directive import multipletimes
-  >>> guis = grok.global_utility.get(multipletimes)
-  >>> guis
-  [<grokcore.component.directive.GlobalUtilityInfo object at 0x...>,
-  <grokcore.component.directive.GlobalUtilityInfo object at 0x...>]
-  >>> guis[0].factory
+  >>> guis = grok.global_utility.bind().get(multipletimes)
+  >>> len(guis)
+  2
+
+  >>> factory, provides, name, direct = guis[0]
+  >>> factory
   <class 'grokcore.component.tests.directive.multipletimes.Club'>
-  >>> guis[0].provides
+  >>> provides
   <InterfaceClass grokcore.component.tests.directive.multipletimes.IClub>
-  >>> guis[0].name
+  >>> name
   'foo'
-  >>> guis[1].factory
+
+  >>> factory, provides, name, direct = guis[1]
+  >>> factory
   <class 'grokcore.component.tests.directive.multipletimes.Cave'>
-  >>> guis[1].provides is None
+  >>> provides is None
   True
-  >>> guis[1].name
+  >>> name
   u''
 
 """



More information about the Checkins mailing list