[Checkins] SVN: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/ Fix template inheritance between two different packages if a base module or package is alphabetically sorted smaller than the inherited one.

Sylvain Viollon sylvain at infrae.com
Thu Jan 27 04:21:22 EST 2011


Log message for revision 119972:
  Fix template inheritance between two different packages if a base module or package is alphabetically sorted smaller than the inherited one.
  

Changed:
  U   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/directive.py
  U   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/meta/templates.py
  U   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/meta/views.py
  U   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/templatereg.py
  U   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/templatereg.txt
  A   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package.py
  A   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/
  A   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/__init__.py
  A   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/
  A   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/__init__.py
  A   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/sub.py
  A   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase.py
  A   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase_templates/
  A   grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase_templates/view.pt

-=-
Modified: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/directive.py
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/directive.py	2011-01-27 09:03:03 UTC (rev 119971)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/directive.py	2011-01-27 09:21:22 UTC (rev 119972)
@@ -14,6 +14,7 @@
 """Grok directives.
 """
 import os.path
+import sys
 
 import martian
 from martian.error import GrokImportError
@@ -38,7 +39,13 @@
     store = martian.ONCE
     validate = martian.validateText
 
+    def factory(self, name):
+        # In combination of the name, store from which module the
+        # template is refered.
+        f_locals = sys._getframe(2).f_locals
+        return (f_locals['__module__'], name)
 
+
 class templatedir(martian.Directive):
     scope = martian.MODULE
     store = martian.ONCE

Modified: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/meta/templates.py
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/meta/templates.py	2011-01-27 09:03:03 UTC (rev 119971)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/meta/templates.py	2011-01-27 09:21:22 UTC (rev 119972)
@@ -25,16 +25,17 @@
     martian.priority(1000)
 
     def grok(self, name, instance, module_info, config, **kw):
+        # We set order to 0, to be sure to register templates
+        # first.
         config.action(
             discriminator=None,
             callable=templatereg.register_inline_template,
-            args=(module_info, name, instance)
-            )
+            args=(module_info, name, instance),
+            order=0)
         config.action(
             discriminator=None,
             callable=instance._annotateGrokInfo,
-            args=(name, module_info.dotted_name)
-            )
+            args=(name, module_info.dotted_name))
         return True
 
 
@@ -45,11 +46,13 @@
     martian.priority(999)
 
     def grok(self, name, module, module_info, config, **kw):
+        # We set order to 0, to be sure to register templates
+        # first.
         config.action(
             discriminator=None,
             callable=templatereg.register_directory,
-            args=(module_info,)
-            )
+            args=(module_info,),
+            order=0)
         return True
 
 
@@ -62,6 +65,8 @@
     def grok(self, name, module, module_info, config, **kw):
         if not self._action_registered:
             self._action_registered = True
+            # We set order to 10000 to be sure to check unused
+            # template at the end only.
             config.action(
                 discriminator=None,
                 callable=templatereg.check_unassociated,

Modified: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/meta/views.py
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/meta/views.py	2011-01-27 09:03:03 UTC (rev 119971)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/meta/views.py	2011-01-27 09:21:22 UTC (rev 119972)
@@ -34,22 +34,33 @@
 class TemplateGrokker(martian.ClassGrokker):
     martian.baseclass()
 
+    _template_order = 5000
+
     def grok(self, name, factory, module_info, **kw):
         # Need to store the module info to look for a template
         factory.module_info = module_info
         return super(TemplateGrokker, self).grok(name, factory, module_info, **kw)
 
     def execute(self, factory, config, **kw):
-        # find templates
+        # Associate templates to a view or a component. We set order
+        # to at least 5000, to do it after all templates have be
+        # registered to the shared template registry, and yet before
+        # unassociated templates are checked.
         config.action(
             discriminator=None,
-            callable=self.check_templates,
-            args=(factory.module_info, factory))
+            callable=self.associate_template,
+            args=(factory.module_info, factory),
+            order=self._template_order)
+        # We increase _template_order to keep a relative order of
+        # association between each different Grok extensions. (Like
+        # this an implicit template can be inherited between two
+        # different Grok extensions.)
+        self._template_order += 1
         return True
 
-    def check_templates(self, module_info, factory):
+    def associate_template(self, module_info, factory):
         component_name = martian.component.bind().get(self).__name__.lower()
-        templatereg.checkTemplates(
+        templatereg.associate_template(
             module_info, factory, component_name, self.has_render, self.has_no_render)
 
     def has_render(self, factory):

Modified: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/templatereg.py
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/templatereg.py	2011-01-27 09:03:03 UTC (rev 119971)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/templatereg.py	2011-01-27 09:21:22 UTC (rev 119972)
@@ -3,6 +3,7 @@
 import zope.component
 import grokcore.component
 import grokcore.view
+from martian.scan import module_info_from_dotted_name
 from martian.error import GrokError
 from grokcore.view.interfaces import ITemplate, ITemplateFileFactory, TemplateLookupError
 from grokcore.view.components import PageTemplate
@@ -207,15 +208,29 @@
         warnings.warn(msg, UserWarning, 1)
 
 
-def checkTemplates(module_info, factory, component_name,
-                   has_render, has_no_render):
+def associate_template(module_info, factory, component_name,
+                       has_render, has_no_render):
+    """Associate a template to a factory located in the module
+    described by module_info.
+    """
     factory_name = factory.__name__.lower()
-    template_name = grokcore.view.template.bind().get(factory)
+    module_name, template_name = grokcore.view.template.bind(
+        default=(None, None)).get(factory)
     if template_name is None:
+        # We didn't used grok.template. Default the template name to
+        # the factory name.
         template_name = factory_name
+    else:
+        # We used grok.template. Use the same module_info to fetch the
+        # template that the module in which the directive have been
+        # used (to get the grok.templatedir value).
+        assert module_name is not None, \
+            u"module_name cannot be None if template_name is specified."
+        module_info = module_info_from_dotted_name(module_name)
 
-    # We used grok.template. Check if there is no template with the
-    # same name as the view
+    # We used grok.template, to specify a template which is different
+    # than the class name. Check if there is no template with the same
+    # name as the view
     if factory_name != template_name:
         try:
             lookup(module_info, factory_name)

Modified: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/templatereg.txt
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/templatereg.txt	2011-01-27 09:03:03 UTC (rev 119971)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/templatereg.txt	2011-01-27 09:21:22 UTC (rev 119972)
@@ -22,7 +22,7 @@
 for inline templates in Python code, and ``register_directory`` for
 templates in directories associated with a module::
 
-  >>> from grokcore.view.templatereg import (register_directory, 
+  >>> from grokcore.view.templatereg import (register_directory,
   ...                                        register_inline_template)
 
 Setup
@@ -31,7 +31,7 @@
 Our templates are ``.template``, so we need to register a
 ``ITemplateFileFactory`` utility for them that knows how to make the
 appropriate templates::
-    
+
   >>> from grokcore.view.interfaces import ITemplateFileFactory, ITemplate
   >>> from zope.interface import implements
   >>> class TestTemplate(object):
@@ -57,7 +57,7 @@
   ...        return TestTemplate(os.path.join(_prefix, filename), data)
 
   >>> from zope import component
-  >>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory, 
+  >>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory,
   ...   name='template')
 
 We create a way to create a fake module_info for a (actually
@@ -116,7 +116,7 @@
 
 If we try to look up a template in a directory that doesn't exist, we get
 a TemplateLookupError::
-  
+
   >>> nonexistent_module_info = create_module_info('nonexistent')
   >>> reg.lookup(nonexistent_module_info, 'foo')
   Traceback (most recent call last):
@@ -142,13 +142,13 @@
 
 There is only a single unassociated template left now::
 
-  >>> sorted(reg.unassociated()) 
+  >>> sorted(reg.unassociated())
   ['...bar.template']
 
 Registering the templates directory again should do nothing and thus the unassociated list should be the same::
 
   >>> register_directory(module_info)
-  >>> sorted(reg.unassociated()) 
+  >>> sorted(reg.unassociated())
   ['...bar.template']
 
 We can associate several times a template without error::
@@ -199,9 +199,9 @@
 
 Let's make the template languages ``1`` and ``2`` known::
 
-  >>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory, 
+  >>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory,
   ...   name='1')
-  >>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory, 
+  >>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory,
   ...   name='2')
 
 We now set up a directory which contains 'foo.1' and 'foo.2'. These
@@ -221,7 +221,7 @@
   >>> register_directory(module_info3)
   Traceback (most recent call last):
     ...
-  GrokError: Conflicting templates found for name 'foo' in directory '...': 
+  GrokError: Conflicting templates found for name 'foo' in directory '...':
   multiple templates with the same name and different extensions.
 
 Inline templates
@@ -250,7 +250,7 @@
 
   >>> inline_reg.lookup(module_info4, 'cavepainting')
   <InlineTemplate 'cavepainting'>
-  
+
 If we cannot find the template we get an error::
 
   >>> inline_reg.lookup(module_info4, 'unknown')
@@ -272,9 +272,9 @@
 
   >>> sorted(inline_reg.unassociated())
   []
-  
+
 We can associate several times an inline template without error::
-  
+
   >>> inline_reg.associate(module_info4, 'cavepainting')
 
 
@@ -361,35 +361,35 @@
   >>> register_inline_template(module_info5, 'foo', InlineTemplate('foo'))
   Traceback (most recent call last):
      ...
-  GrokError: Conflicting templates found for name 'foo': the inline template 
-  in module 'module5' conflicts with the file template in directory 
+  GrokError: Conflicting templates found for name 'foo': the inline template
+  in module 'module5' conflicts with the file template in directory
   '...module5_templates'
 
 Let's now demonstrate the same conflict, the other way around.
 
-First we set up a fictional filesystem structure surrounding a 
+First we set up a fictional filesystem structure surrounding a
 ``module6``::
 
   >>> module_info6, template_dir6 = create_module_info_with_templates('module6')
- 
+
 We add a template to it::
 
   >>> f = open(os.path.join(template_dir6, 'bar.template'), 'w')
   >>> f.write('bar')
   >>> f.close()
- 
+
 Now we first register an inline template ``bar`` before loading up that
 directory::
 
   >>> register_inline_template(module_info6, 'bar', InlineTemplate('bar'))
- 
+
 When we now try to register the template ``bar`` in a directory, we'll
 get an error::
 
    >>> register_directory(module_info6)
    Traceback (most recent call last):
      ...
-   GrokError: Conflicting templates found for name 'bar': 
+   GrokError: Conflicting templates found for name 'bar':
    the inline template in module 'module6' conflicts with the file template in directory '...'
 
 

Added: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package.py
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package.py	                        (rev 0)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package.py	2011-01-27 09:21:22 UTC (rev 119972)
@@ -0,0 +1,7 @@
+"""
+  >>> import cross_package_fixture
+
+  >>> grok.testing.grok(cross_package_fixture.__name__)
+
+"""
+import grokcore.view as grok


Property changes on: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package.py
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision

Added: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/__init__.py
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/__init__.py	                        (rev 0)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/__init__.py	2011-01-27 09:21:22 UTC (rev 119972)
@@ -0,0 +1 @@
+# this is a package


Property changes on: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/__init__.py
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision

Added: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/__init__.py
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/__init__.py	                        (rev 0)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/__init__.py	2011-01-27 09:21:22 UTC (rev 119972)
@@ -0,0 +1 @@
+# this is a package


Property changes on: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/__init__.py
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision

Added: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/sub.py
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/sub.py	                        (rev 0)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/sub.py	2011-01-27 09:21:22 UTC (rev 119972)
@@ -0,0 +1,6 @@
+
+from grokcore.view.tests.view.cross_package_fixture.zbase import BaseView
+
+class SubView(BaseView):
+    pass
+


Property changes on: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/subpackage/sub.py
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision

Added: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase.py
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase.py	                        (rev 0)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase.py	2011-01-27 09:21:22 UTC (rev 119972)
@@ -0,0 +1,8 @@
+#
+
+import grokcore.view as grok
+
+class BaseView(grok.View):
+    grok.template('view')
+    grok.context(object)
+


Property changes on: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase.py
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision

Added: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase_templates/view.pt
===================================================================
--- grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase_templates/view.pt	                        (rev 0)
+++ grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase_templates/view.pt	2011-01-27 09:21:22 UTC (rev 119972)
@@ -0,0 +1 @@
+<p>View template</p>


Property changes on: grokcore.view/branches/sylvain-template-inheritance-fix/src/grokcore/view/tests/view/cross_package_fixture/zbase_templates/view.pt
___________________________________________________________________
Added: svn:keywords
   + Author Date Id Revision



More information about the checkins mailing list