[Checkins] SVN: grokcore.component/trunk/ Merged the jw-philipp-using-ndir-directives branch.

Philipp von Weitershausen philikon at philikon.de
Sun May 4 11:09:28 EDT 2008


Log message for revision 86383:
  Merged the jw-philipp-using-ndir-directives branch.
  

Changed:
  U   grokcore.component/trunk/CHANGES.txt
  U   grokcore.component/trunk/setup.py
  U   grokcore.component/trunk/src/grokcore/component/__init__.py
  U   grokcore.component/trunk/src/grokcore/component/directive.py
  U   grokcore.component/trunk/src/grokcore/component/meta.py
  A   grokcore.component/trunk/src/grokcore/component/scan.py
  U   grokcore.component/trunk/src/grokcore/component/testing.py
  U   grokcore.component/trunk/src/grokcore/component/tests/adapter/classcontextmultiple.py
  U   grokcore.component/trunk/src/grokcore/component/tests/adapter/classorinterface.py
  U   grokcore.component/trunk/src/grokcore/component/tests/adapter/conflict.py
  U   grokcore.component/trunk/src/grokcore/component/tests/adapter/functioncontext.py
  U   grokcore.component/trunk/src/grokcore/component/tests/adapter/importedmodel2.py
  U   grokcore.component/trunk/src/grokcore/component/tests/adapter/modulecontextmultiple.py
  U   grokcore.component/trunk/src/grokcore/component/tests/adapter/multiadaptsnone.py
  U   grokcore.component/trunk/src/grokcore/component/tests/adapter/multiple.py
  U   grokcore.component/trunk/src/grokcore/component/tests/adapter/nomodel.py
  U   grokcore.component/trunk/src/grokcore/component/tests/directive/argumenterror.py
  U   grokcore.component/trunk/src/grokcore/component/tests/directive/argumenterror_fixture.py
  U   grokcore.component/trunk/src/grokcore/component/tests/directive/multipletimes.py
  A   grokcore.component/trunk/src/grokcore/component/tests/grok_component.txt
  U   grokcore.component/trunk/src/grokcore/component/tests/grokker/grokcomponent.py
  D   grokcore.component/trunk/src/grokcore/component/tests/order/
  D   grokcore.component/trunk/src/grokcore/component/tests/scan_for_module_components.txt
  D   grokcore.component/trunk/src/grokcore/component/tests/scan_for_module_components_fixture/
  U   grokcore.component/trunk/src/grokcore/component/tests/test_grok.py
  D   grokcore.component/trunk/src/grokcore/component/tests/util/
  U   grokcore.component/trunk/src/grokcore/component/tests/view/nomodulename.py
  D   grokcore.component/trunk/src/grokcore/component/util.py
  U   grokcore.component/trunk/versions.cfg

-=-
Modified: grokcore.component/trunk/CHANGES.txt
===================================================================
--- grokcore.component/trunk/CHANGES.txt	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/CHANGES.txt	2008-05-04 15:09:28 UTC (rev 86383)
@@ -4,8 +4,17 @@
 1.2 (unreleased)
 ----------------
 
-* ...
+* Ported directives to Martian's new directive implementation.  As a
+  result, nearly all helper functions that were available from
+  ``grokcore.component.util`` have been removed.  The functionality is
+  mostly available from the directives themselves now.
 
+* The ``baseclass`` directive has been moved to Martian.
+
+* The ``order`` directive and its helper functions have been moved
+  back to Grok, as it was of no general use, but very specific to
+  viewlets.
+
 1.1 (2008-05-03)
 ----------------
 

Modified: grokcore.component/trunk/setup.py
===================================================================
--- grokcore.component/trunk/setup.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/setup.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -32,7 +32,7 @@
     include_package_data=True,
     zip_safe=False,
     install_requires=['setuptools',
-                      'martian >= 0.9.3',
+                      'martian >= 0.9.4',
                       'zope.component',
                       'zope.configuration',
                       'zope.interface',

Modified: grokcore.component/trunk/src/grokcore/component/__init__.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/__init__.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/__init__.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -20,9 +20,9 @@
 from martian import ClassGrokker, InstanceGrokker, GlobalGrokker
 from grokcore.component.components import Adapter, GlobalUtility, MultiAdapter, Context
 
-from grokcore.component.directive import (context, name, title,
-                            provides, baseclass, global_utility,
-                            direct, order)
+from martian import baseclass
+from grokcore.component.directive import (
+    context, name, title, description, provides, global_utility, direct)
 from grokcore.component.decorators import subscribe, adapter, implementer
 from martian.error import GrokError, GrokImportError
 

Modified: grokcore.component/trunk/src/grokcore/component/directive.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/directive.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/directive.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -13,78 +13,71 @@
 ##############################################################################
 """Grok directives.
 """
-
+import types
+import martian
+import grokcore.component
 from zope.interface.interfaces import IInterface
-
 from martian.error import GrokImportError
-from martian.directive import (OnceDirective,
-                               MultipleTimesDirective,
-                               SingleTextDirective,
-                               MarkerDirective,
-                               InterfaceDirective,
-                               InterfaceOrClassDirective,
-                               ModuleDirectiveContext,
-                               OptionalValueDirective,
-                               ClassDirectiveContext,
-                               ClassOrModuleDirectiveContext)
-from martian import util
+from grokcore.component.scan import check_module_component
 
-class GlobalUtilityDirective(MultipleTimesDirective):
-    def check_arguments(self, factory, provides=None, name=u'',
-                        direct=False):
+class global_utility(martian.MultipleTimesDirective):
+    scope = martian.MODULE
+
+    def factory(self, factory, provides=None, name=u'', direct=False):
         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)
+            raise GrokImportError(
+                "You can only pass an interface to the "
+                "provides argument of %s." % self.name)
+        return GlobalUtilityInfo(factory, provides, name, direct)
 
-    def value_factory(self, *args, **kw):
-        return GlobalUtilityInfo(*args, **kw)
-
-
 class GlobalUtilityInfo(object):
+
     def __init__(self, factory, provides=None, name=u'', direct=None):
         self.factory = factory
         if direct is None:
-            direct = util.class_annotation(factory, 'grok.direct', False)
+            direct = grokcore.component.direct.get(factory)
         self.direct = direct
 
         if provides is None:
-            provides = util.class_annotation(factory, 'grok.provides', None)
+            provides = grokcore.component.provides.get(factory)
         self.provides = provides
 
         if name is u'':
-            name = util.class_annotation(factory, 'grok.name', u'')
+            name = grokcore.component.name.get(factory)
         self.name = name
 
+class name(martian.Directive):
+    scope = martian.CLASS
+    store = martian.ONCE
+    default = u''
+    validate = martian.validateText
 
-class MultiValueOnceDirective(OnceDirective):
+class context(martian.Directive):
+    scope = martian.CLASS_OR_MODULE
+    store = martian.ONCE
+    validate = martian.validateInterfaceOrClass
 
-    def check_arguments(self, *values):
-        pass
+    @classmethod
+    def get(cls, component, module=None):
+        value = super(cls, context).get(component, module)
+        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
 
-    def value_factory(self, *args):
-        return args
+class title(martian.Directive):
+    scope = martian.CLASS
+    store = martian.ONCE
+    validate = martian.validateText
 
-class OrderDirective(OptionalValueDirective, OnceDirective):
+class description(title):
+    pass
 
-    order = 0
+class direct(martian.MarkerDirective):
+    scope = martian.CLASS
 
-    def value_factory(self, value=None):
-        OrderDirective.order += 1
-        if value is not None:
-            return value, OrderDirective.order
-        return super(OrderDirective, self).value_factory(value)
-
-    def default_value(self):
-        return 0, OrderDirective.order
-
-# Define grok directives
-name = SingleTextDirective('grok.name', ClassDirectiveContext())
-context = InterfaceOrClassDirective('grok.context',
-                                    ClassOrModuleDirectiveContext())
-provides = InterfaceDirective('grok.provides', ClassDirectiveContext())
-baseclass = MarkerDirective('grok.baseclass', ClassDirectiveContext())
-global_utility = GlobalUtilityDirective('grok.global_utility',
-                                        ModuleDirectiveContext())
-title = SingleTextDirective('grok.title', ClassDirectiveContext())
-order = OrderDirective('grok.order', ClassDirectiveContext())
-direct = MarkerDirective('grok.direct', ClassDirectiveContext())
+class provides(martian.Directive):
+    scope = martian.CLASS
+    store = martian.ONCE
+    validate = martian.validateInterface

Modified: grokcore.component/trunk/src/grokcore/component/meta.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/meta.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/meta.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -13,39 +13,22 @@
 ##############################################################################
 """Grokkers for the various components."""
 
-import martian
+import martian.util
 import grokcore.component
 import zope.component.interface
 
 from zope import component, interface
-from martian import util
 from martian.error import GrokError
-from grokcore.component.util import check_adapts
-from grokcore.component.util import check_module_component
-from grokcore.component.util import determine_module_component
-from grokcore.component.util import determine_class_component
-from grokcore.component.util import check_provides_one
+from grokcore.component.scan import check_module_component
+from grokcore.component.scan import determine_module_component
 from grokcore.component.interfaces import IContext
+from grokcore.component.interfaces import IContext
 
-def get_context(module_info, factory):
-    return determine_class_component(module_info, factory,
-                                     'context', 'grok.context')
-
-def get_name_classname(factory):
-    return get_name(factory, factory.__name__.lower())
-
-def get_name(factory, default=''):
-    return grokcore.component.util.class_annotation(factory, 'grok.name',
-                                                    default)
-
-def get_title(factory, default=''):
-    return grokcore.component.util.class_annotation(factory, 'grok.title',
-                                                    default)
-
 def get_provides(factory):
-    provides = util.class_annotation(factory, 'grok.provides', None)
+    provides = grokcore.component.provides.get(factory)
+
     if provides is None:
-        util.check_implements_one(factory)
+        martian.util.check_implements_one(factory)
         provides = list(interface.implementedBy(factory))[0]
     return provides
 
@@ -55,9 +38,10 @@
     priority = 1001
 
     def grok(self, name, module, module_info, config, **kw):
-        context = determine_module_component(module_info, 'grok.context',
+        context = determine_module_component(module_info,
+                                             grokcore.component.context,
                                              IContext)
-        module.__grok_context__ = context
+        grokcore.component.context.set(module, context)
         return True
 
 
@@ -65,10 +49,10 @@
     component_class = grokcore.component.Adapter
 
     def grok(self, name, factory, module_info, config, **kw):
-        adapter_context = get_context(module_info, factory)
+        adapter_context = grokcore.component.context.get(factory, module_info.getModule())
         provides = get_provides(factory)
-        name = get_name(factory)
-        
+        name = grokcore.component.name.get(factory)
+
         config.action(
             discriminator=('adapter', adapter_context, provides, name),
             callable=component.provideAdapter,
@@ -82,9 +66,12 @@
 
     def grok(self, name, factory, module_info, config, **kw):
         provides = get_provides(factory)
-        name = get_name(factory)
-        
-        check_adapts(factory)
+        name = grokcore.component.name.get(factory)
+
+        if component.adaptedBy(factory) is None:
+            raise GrokError("%r must specify which contexts it adapts "
+                            "(use the 'adapts' directive to specify)."
+                            % factory, factory)
         for_ = component.adaptedBy(factory)
 
         config.action(
@@ -103,14 +90,14 @@
     priority = 1100
 
     def grok(self, name, factory, module_info, config, **kw):
-        provides = util.class_annotation(factory, 'grok.provides', None)
-        direct = util.class_annotation(factory, 'grok.direct', False)
-        name = get_name(factory)
+        provides = grokcore.component.provides.get(factory)
+        direct = grokcore.component.direct.get(factory)
+        name = grokcore.component.name.get(factory)
 
         if direct:
             obj = factory
             if provides is None:
-                check_provides_one(factory)
+                martian.util.check_provides_one(factory)
                 provides = list(interface.providedBy(factory))[0]
         else:
             obj = factory()
@@ -128,15 +115,15 @@
 class AdapterDecoratorGrokker(martian.GlobalGrokker):
 
     def grok(self, name, module, module_info, config, **kw):
-        context = module_info.getAnnotation('grok.context', None)
+        context = grokcore.component.context.get(module)
         implementers = module_info.getAnnotation('implementers', [])
         for function in implementers:
             interfaces = getattr(function, '__component_adapts__', None)
             if interfaces is None:
                 # There's no explicit interfaces defined, so we assume the
                 # module context to be the thing adapted.
-                check_module_component(module_info.getModule(), context,
-                                       'context', 'grok.context')
+                check_module_component(function, context, 'context',
+                                       grokcore.component.context)
                 interfaces = (context, )
 
             config.action(
@@ -150,7 +137,7 @@
 class GlobalUtilityDirectiveGrokker(martian.GlobalGrokker):
 
     def grok(self, name, module, module_info, config, **kw):
-        infos = module_info.getAnnotation('grok.global_utility', [])
+        infos = grokcore.component.global_utility.get(module)
 
         for info in infos:
             provides = info.provides
@@ -158,7 +145,7 @@
             if info.direct:
                 obj = info.factory
                 if provides is None:
-                    check_provides_one(obj)
+                    martian.util.check_provides_one(obj)
                     provides = list(interface.providedBy(obj))[0]
             else:
                 obj = info.factory()

Copied: grokcore.component/trunk/src/grokcore/component/scan.py (from rev 86382, grokcore.component/branches/jw-philipp-using-ndir-directives/src/grokcore/component/scan.py)
===================================================================
--- grokcore.component/trunk/src/grokcore/component/scan.py	                        (rev 0)
+++ grokcore.component/trunk/src/grokcore/component/scan.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -0,0 +1,70 @@
+##############################################################################
+#
+# Copyright (c) 2006-2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Grok utility functions.
+"""
+
+from martian.error import GrokError
+from martian.util import methods_from_class, scan_for_classes
+
+AMBIGUOUS_COMPONENT = object()
+def check_module_component(factory, component, component_name, directive):
+    """Raise error if module-level component cannot be determined.
+
+    If the module-level component is None, it's never been specified;
+    raise error telling developer to specify.
+
+    if the module-level component is AMBIGUOUS_COMPONENT, raise
+    an error telling developer to specify which one to use.
+    """
+    if component is None:
+        raise GrokError("No module-level %s for %r, please use the '%s' "
+                        "directive."
+                        % (component_name, factory, directive.__name__),
+                        factory)
+    elif component is AMBIGUOUS_COMPONENT:
+        raise GrokError("Multiple possible %ss for %r, please use the '%s' "
+                        "directive."
+                        % (component_name, factory, directive.__name__),
+                        factory)
+    
+def determine_module_component(module_info, directive, iface):
+    """Determine module-level component.
+
+    The module-level component can be set explicitly using the
+    annotation (such as grok.context).
+
+    If there is no annotation, the module-level component is determined
+    by scanning for classes that implement an interface.
+    
+    If there is no module-level component, the module-level component is
+    None.
+
+    If there is one module-level component, it is returned.
+
+    If there are more than one module-level component, AMBIGUOUS_COMPONENT
+    is returned.
+    """
+    module = module_info.getModule()
+    components = list(scan_for_classes(module, interface=iface))
+    if len(components) == 0:
+        component = None
+    elif len(components) == 1:
+        component = components[0]
+    else:
+        component= AMBIGUOUS_COMPONENT
+
+    module_component = directive.get(module)
+    if module_component is not None:
+        component = module_component
+    return component

Modified: grokcore.component/trunk/src/grokcore/component/testing.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/testing.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/testing.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -13,6 +13,7 @@
 ##############################################################################
 """Grok test helpers
 """
+import grokcore.component
 from zope.configuration.config import ConfigurationMachine
 from martian import scan
 from grokcore.component import zcml
@@ -172,7 +173,7 @@
 
     module = module_info.getModule()
     if context is not None:
-        module.__grok_context__ = context
+        grokcore.component.context.set(module, context)
     if templates is not None:
         module.__grok_templates__ = templates
     config = ConfigurationMachine()

Modified: grokcore.component/trunk/src/grokcore/component/tests/adapter/classcontextmultiple.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/adapter/classcontextmultiple.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/adapter/classcontextmultiple.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -4,7 +4,8 @@
   >>> import grokcore.component.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: grokcore.component/trunk/src/grokcore/component/tests/adapter/classorinterface.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/adapter/classorinterface.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/adapter/classorinterface.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -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 grokcore.component as grok

Modified: grokcore.component/trunk/src/grokcore/component/tests/adapter/conflict.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/adapter/conflict.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/adapter/conflict.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -7,7 +7,7 @@
   Traceback (most recent call last):
   ...
   ConfigurationConflictError: Conflicting configuration actions
-    For: ('adapter', <InterfaceClass grokcore.component.tests.adapter.conflict.ICave>, <InterfaceClass grokcore.component.tests.adapter.conflict.IDecoration>, '')
+    For: ('adapter', <InterfaceClass grokcore.component.tests.adapter.conflict.ICave>, <InterfaceClass grokcore.component.tests.adapter.conflict.IDecoration>, u'')
 
 """
 import grokcore.component as grok

Modified: grokcore.component/trunk/src/grokcore/component/tests/adapter/functioncontext.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/adapter/functioncontext.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/adapter/functioncontext.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -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 grokcore.component as grok

Modified: grokcore.component/trunk/src/grokcore/component/tests/adapter/importedmodel2.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/adapter/importedmodel2.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/adapter/importedmodel2.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -5,7 +5,8 @@
   Traceback (most recent call last):
     ...
   GrokError: No module-level context for
-  <class 'grokcore.component.tests.adapter.importedmodel2.Painting'>, please use grok.context.
+  <class 'grokcore.component.tests.adapter.importedmodel2.Painting'>,
+  please use the 'context' directive.
 
 """
 import grokcore.component as grok

Modified: grokcore.component/trunk/src/grokcore/component/tests/adapter/modulecontextmultiple.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/adapter/modulecontextmultiple.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/adapter/modulecontextmultiple.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -4,6 +4,7 @@
   >>> import grokcore.component.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: grokcore.component/trunk/src/grokcore/component/tests/adapter/multiadaptsnone.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/adapter/multiadaptsnone.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/adapter/multiadaptsnone.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -4,8 +4,8 @@
   >>> grok.testing.grok(__name__)
   Traceback (most recent call last):
     ...
-  GrokError: <class 'grokcore.component.tests.adapter.multiadaptsnone.Home'> must specify
-  which contexts it adapts (use grok.adapts to specify).
+  GrokError: <class 'grokcore.component.tests.adapter.multiadaptsnone.Home'>
+  must specify which contexts it adapts (use the 'adapts' directive to specify).
 """
 import grokcore.component as grok
 

Modified: grokcore.component/trunk/src/grokcore/component/tests/adapter/multiple.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/adapter/multiple.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/adapter/multiple.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -5,7 +5,8 @@
   Traceback (most recent call last):
     ...
   GrokError: Multiple possible contexts for
-  <class 'grokcore.component.tests.adapter.multiple.Home'>, please use grok.context.
+  <class 'grokcore.component.tests.adapter.multiple.Home'>, please use the
+  'context' directive.
 
 """
 import grokcore.component as grok

Modified: grokcore.component/trunk/src/grokcore/component/tests/adapter/nomodel.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/adapter/nomodel.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/adapter/nomodel.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -5,7 +5,7 @@
   Traceback (most recent call last):
     ...
   GrokError: No module-level context for
-  <class 'grokcore.component.tests.adapter.nomodel.Home'>, please use grok.context.
+  <class 'grokcore.component.tests.adapter.nomodel.Home'>, please use the 'context' directive.
 
 """
 import grokcore.component as grok

Modified: grokcore.component/trunk/src/grokcore/component/tests/directive/argumenterror.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/directive/argumenterror.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/directive/argumenterror.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -2,5 +2,6 @@
    >>> import grokcore.component.tests.directive.argumenterror_fixture
    Traceback (most recent call last):
      ...
-   TypeError: grok.name takes exactly 1 argument (3 given)
+   TypeError: name takes exactly 1 argument (3 given)
+
 """

Modified: grokcore.component/trunk/src/grokcore/component/tests/directive/argumenterror_fixture.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/directive/argumenterror_fixture.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/directive/argumenterror_fixture.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -1,3 +1,4 @@
 import grokcore.component as grok
 
-grok.name('too', 'many', 'arguments')
+class Foo(object):
+    grok.name('too', 'many', 'arguments')

Modified: grokcore.component/trunk/src/grokcore/component/tests/directive/multipletimes.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/directive/multipletimes.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/directive/multipletimes.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -2,10 +2,11 @@
 Since grok.global_utility is a MultipleTimesDirective, there is a list of
 GlobalUtilityInfo objects annotated on the module.
 
+
   >>> from martian import scan
+  >>> import grokcore.component as grok
   >>> from grokcore.component.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...>]
@@ -21,7 +22,7 @@
   True
   >>> guis[1].name
   u''
-  
+
 """
 import grokcore.component as grok
 from zope import interface

Copied: grokcore.component/trunk/src/grokcore/component/tests/grok_component.txt (from rev 86382, grokcore.component/branches/jw-philipp-using-ndir-directives/src/grokcore/component/tests/grok_component.txt)
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/grok_component.txt	                        (rev 0)
+++ grokcore.component/trunk/src/grokcore/component/tests/grok_component.txt	2008-05-04 15:09:28 UTC (rev 86383)
@@ -0,0 +1,42 @@
+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).
+
+grokcore.component.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 grokcore.component as grok
+  >>> class MyAdapter(grok.Adapter):
+  ...    grok.provides(IFoo)
+  ...    grok.context(Bar)
+
+Now we will register the adapter using grok_component()::
+
+  >>> from grokcore.component.testing import grok, grok_component
+  >>> grok('grokcore.component.meta')
+  >>> grok_component('MyAdapter', MyAdapter)
+  True
+  
+The adapter should now be available::
+
+  >>> adapted = IFoo(Bar())
+  >>> isinstance(adapted, MyAdapter)
+  True

Modified: grokcore.component/trunk/src/grokcore/component/tests/grokker/grokcomponent.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/grokker/grokcomponent.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/grokker/grokcomponent.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -43,7 +43,7 @@
   >>> grok.testing.grok_component('SecondAdapter', SecondAdapter)
   Traceback (most recent call last):
     ...
-  GrokError: No module-level context for <class 'grokcore.component.tests.grokker.grokcomponent.SecondAdapter'>, please use grok.context.
+  GrokError: No module-level context for <class 'grokcore.component.tests.grokker.grokcomponent.SecondAdapter'>, please use the 'context' directive.
 
 So we need to supply the context ourselves::
 

Deleted: grokcore.component/trunk/src/grokcore/component/tests/scan_for_module_components.txt
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/scan_for_module_components.txt	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/scan_for_module_components.txt	2008-05-04 15:09:28 UTC (rev 86383)
@@ -1,32 +0,0 @@
-Scanning for the context object
--------------------------------
-
-Let's import a module that contains no ``Context`` subclass, nor classes
-that implement ``IContext``::
-
-  >>> import grokcore.component.tests.scan_for_module_components_fixture as tests
-  >>> from grokcore.component.interfaces import IContext
-
-We shouldn't see any classes that are contexts::
-
-  >>> from grokcore.component.util import scan_for_module_components
-  >>> scan_for_module_components(tests.test1, IContext)
-  []
-
-Now we look at a module with a single ``Context`` subclass::
-
-  >>> scan_for_module_components(tests.test2, IContext)
-  [<class 'grokcore.component.tests.scan_for_module_components_fixture.test2.MyContext'>]
-
-Now we'll look at a module with a single class that implements ``IContext``::
-
-  >>> scan_for_module_components(tests.test3, IContext)
-  [<class 'grokcore.component.tests.scan_for_module_components_fixture.test3.MyContext'>]
-
-Let's finish by looking at a module which defines multiple contexts::
-
-  >>> len(scan_for_module_components(tests.test4, IContext))
-  4
-
-
-

Modified: grokcore.component/trunk/src/grokcore/component/tests/test_grok.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/test_grok.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/test_grok.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -45,13 +45,16 @@
 
 def test_suite():
     suite = unittest.TestSuite()
-    for name in ['adapter', 'directive', 'grokker', 'order', 'testsetup',
-                 'util', 'utility', 'view', 'event']:
+    for name in ['adapter', 'directive', 'grokker', 'testsetup',
+                 'utility', 'view', 'event']:
         suite.addTest(suiteFromPackage(name))
 
-    suite.addTest(doctest.DocFileSuite(
-            'scan_for_module_components.txt',
-            optionflags=doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE))
+    # 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',
+                                          setUp=setUpZope,
+                                          tearDown=cleanUpZope)
+    suite.addTest(grok_component)
     return suite
 
 if __name__ == '__main__':

Modified: grokcore.component/trunk/src/grokcore/component/tests/view/nomodulename.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/tests/view/nomodulename.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/tests/view/nomodulename.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -4,6 +4,6 @@
   >>> import grokcore.component.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.
 
 """

Deleted: grokcore.component/trunk/src/grokcore/component/util.py
===================================================================
--- grokcore.component/trunk/src/grokcore/component/util.py	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/src/grokcore/component/util.py	2008-05-04 15:09:28 UTC (rev 86383)
@@ -1,140 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006-2007 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Grok utility functions.
-"""
-
-from zope import component, interface
-
-from martian.error import GrokError
-from martian.util import class_annotation, defined_locally, isclass
-
-from grokcore.component.interfaces import IContext
-
-def check_adapts(class_):
-    if component.adaptedBy(class_) is None:
-        raise GrokError("%r must specify which contexts it adapts "
-                        "(use grok.adapts to specify)."
-                        % class_, class_)
-
-def determine_class_directive(directive_name, factory, module_info,
-                              default=None):
-    directive = class_annotation(factory, directive_name, None)
-    if directive is None:
-        directive = module_info.getAnnotation(directive_name, None)
-    if directive is not None:
-        return directive
-    return default
-
-def _sort_key(component):
-    explicit_order, implicit_order = class_annotation(component,
-                                                      'grok.order',
-                                                      (0,0))
-    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)
-
-AMBIGUOUS_COMPONENT = object()
-def check_module_component(factory, component,
-                           component_name, component_directive):
-    """Raise error if module-level component cannot be determined.
-
-    If the module-level component is None, it's never been specified;
-    raise error telling developer to specify.
-
-    if the module-level component is AMBIGUOUS_COMPONENT, raise
-    an error telling developer to specify which one to use.
-    """
-    if component is None:
-        raise GrokError("No module-level %s for %r, please use "
-                        "%s." % (component_name, factory, component_directive),
-                        factory)
-    elif component is AMBIGUOUS_COMPONENT:
-        raise GrokError("Multiple possible %ss for %r, please use "
-                        "%s." % (component_name, factory, component_directive),
-                        factory)
-
-def scan_for_module_components(module, iface):
-    """Given a module, scan for classes that that implements an interface.
-    """
-    result = set()
-    for name in dir(module):
-        if name.startswith('__grok_'):
-            continue
-        obj = getattr(module, name)
-        if not defined_locally(obj, module.__name__):
-            continue
-        
-        if isclass(obj) and iface.implementedBy(obj):
-            result.add(obj)
-    return list(result)
-    
-def determine_module_component(module_info, annotation, iface):
-    """Determine module-level component.
-
-    The module-level component can be set explicitly using the
-    annotation (such as grok.context).
-
-    If there is no annotation, the module-level component is determined
-    by scanning for classes that implement an interface.
-    
-    If there is no module-level component, the module-level component is
-    None.
-
-    If there is one module-level component, it is returned.
-
-    If there are more than one module-level component, AMBIGUOUS_COMPONENT
-    is returned.
-    """
-    components = scan_for_module_components(module_info.getModule(), iface)
-    if len(components) == 0:
-        component = None
-    elif len(components) == 1:
-        component = components[0]
-    else:
-        component= AMBIGUOUS_COMPONENT
-        
-    module_component = module_info.getAnnotation(annotation, None)
-    if module_component:
-        component = module_component
-    return component
-
-
-def determine_class_component(module_info, class_,
-                              component_name, component_directive):
-    """Determine component for a class.
-
-    Determine a component for a class. If no class-specific component exists,
-    try falling back on module-level component.
-    """
-    module_component = module_info.getAnnotation(component_directive, None)
-    component = class_annotation(class_, component_directive, module_component)
-    check_module_component(class_, component,
-                           component_name, component_directive)
-    return component
-
-def check_provides_one(obj):
-    provides = list(interface.providedBy(obj))
-    if len(provides) < 1:
-        raise GrokError("%r must provide at least one interface "
-                        "(use zope.interface.classProvides to specify)."
-                        % obj, obj)
-    if len(provides) > 1:
-        raise GrokError("%r provides more than one interface "
-                        "(use grok.provides to specify which one to use)."
-                        % obj, obj)

Modified: grokcore.component/trunk/versions.cfg
===================================================================
--- grokcore.component/trunk/versions.cfg	2008-05-04 15:00:39 UTC (rev 86382)
+++ grokcore.component/trunk/versions.cfg	2008-05-04 15:09:28 UTC (rev 86383)
@@ -1,5 +1,5 @@
 [versions]
-martian = 0.9.3
+martian = 0.9.4
 zope.configuration = 3.4.0
 zope.deferredimport = 3.4.0
 zope.deprecation = 3.4.0



More information about the Checkins mailing list