[Checkins] SVN: grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/ Refactoring of the registration functions. The only way to call

Martijn Faassen faassen at startifact.com
Sat Jul 4 12:27:52 EDT 2009


Log message for revision 101547:
  Refactoring of the registration functions. The only way to call
  register_directory is now using a module_info. Both registering a
  directory and registering inline templates check the other registry
  to see whether there is no conflict.
  

Changed:
  U   grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/interfaces.py
  U   grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.py
  U   grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.txt

-=-
Modified: grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/interfaces.py
===================================================================
--- grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/interfaces.py	2009-07-04 15:23:37 UTC (rev 101546)
+++ grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/interfaces.py	2009-07-04 16:27:51 UTC (rev 101547)
@@ -162,3 +162,6 @@
 
     def render(view):
         """Renders the template"""
+
+class TemplateLookupError(Exception):
+    pass

Modified: grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.py
===================================================================
--- grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.py	2009-07-04 15:23:37 UTC (rev 101546)
+++ grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.py	2009-07-04 16:27:51 UTC (rev 101547)
@@ -4,16 +4,33 @@
 import grokcore.component
 import grokcore.view
 from martian.error import GrokError
-from grokcore.view.interfaces import ITemplateFileFactory
+from grokcore.view.interfaces import ITemplateFileFactory, TemplateLookupError
 from grokcore.view.components import PageTemplate
-        
 
+
 class InlineTemplateRegistry(object):
     def __init__(self):
         self._reg = {}
         self._unassociated = set()
 
+
     def register_inline_template(self, module_info, template_name, template):
+        # verify no file template got registered with the same name
+        template_dir = file_template_registry.get_template_dir(module_info)
+
+        try:
+            existing_template = file_template_registry.lookup(
+                template_dir, template_name)
+        except TemplateLookupError:
+            pass
+        else:
+            raise GrokError("Conflicting templates found for name '%s': "
+                            "the inline template in module '%s' conflicts "
+                            "with the file template in directory '%s'" %
+                            (template_name, module_info.dotted_name,
+                             template_dir), None)
+
+        # register the inline template
         self._reg[(module_info.dotted_name, template_name)] = template
         self._unassociated.add((module_info.dotted_name, template_name))
 
@@ -23,7 +40,7 @@
     def lookup(self, module_info, template_name):
         result = self._reg.get((module_info.dotted_name, template_name))
         if result is None:
-            raise LookupError("inline template '%s' in '%s' cannot be found" % (
+            raise TemplateLookupError("inline template '%s' in '%s' cannot be found" % (
                     template_name, module_info.dotted_name))
         return result
     
@@ -35,24 +52,21 @@
         self._reg = {}
         self._unassociated = set()
 
-    def register_directory_for_module(self, module_info):
+    def register_directory(self, module_info):
         # we cannot register a templates dir for a package
         if module_info.isPackage():
             return
 
         template_dir = self.get_template_dir(module_info)
-        self.register_directory(template_dir)
-        
-    def register_directory(self, template_dir):
         # we can only register for directories
         if not os.path.isdir(template_dir):
             return
-        
+    
         for template_file in os.listdir(template_dir):
-            self._register_template_file(
-                os.path.join(template_dir, template_file))
-
-    def _register_template_file(self, template_path):
+            template_path = os.path.join(template_dir, template_file)
+            self._register_template_file(module_info, template_path)
+        
+    def _register_template_file(self, module_info, template_path):
         template_dir, template_file = os.path.split(template_path)
 
         if template_file.startswith('.') or template_file.endswith('~'):
@@ -61,22 +75,24 @@
             # chameleon creates '<tpl_name>.cache' files on the fly
             return
 
-#             inline_template = self.getLocal(template_name)
-#             if inline_template:
-#                 raise GrokError("Conflicting templates found for name '%s' "
-#                                 "in module %r, either inline and in template "
-#                                 "directory '%s', or two templates with the "
-#                                 "same name and different extensions."
-#                                 % (template_name, module_info.getModule(),
-#                                    template_dir), inline_template)
-
         template_name, extension = os.path.splitext(template_file)
         if (template_dir, template_name) in self._reg:
             raise GrokError("Conflicting templates found for name '%s' "
                             "in directory '%s': multiple templates with "
                             "the same name and different extensions ." %
                             (template_name, template_dir), None)
-                    
+        # verify no inline template exists with the same name
+        try:
+            inline_template_registry.lookup(module_info, template_name)
+        except TemplateLookupError:
+            pass
+        else:
+            raise GrokError("Conflicting templates found for name '%s': "
+                            "the inline template in module '%s' conflicts "
+                            "with the file template in directory '%s'" %
+                            (template_name, module_info.dotted_name,
+                             template_dir), None)
+        
         extension = extension[1:] # Get rid of the leading dot.
         template_factory = zope.component.queryUtility(
             grokcore.view.interfaces.ITemplateFileFactory,
@@ -103,7 +119,7 @@
     def lookup(self, template_dir, template_name):
         result = self._reg.get((template_dir, template_name))
         if result is None:
-            raise LookupError("template '%s' in '%s' cannot be found" % (
+            raise TemplateLookupError("template '%s' in '%s' cannot be found" % (
                     template_name, template_dir))
         return result
     
@@ -122,30 +138,10 @@
 inline_template_registry = InlineTemplateRegistry()
 file_template_registry = FileTemplateRegistry()
 
-def register_inline_template(module_info, template_name, template):
-    template_dir = file_template_registry.get_template_dir(module_info)
+register_inline_template = inline_template_registry.register_inline_template
 
-    try:
-        existing_template = file_template_registry.lookup(
-            template_dir, template_name)
-    except LookupError:
-        pass # we actually want a LookupError as the template shouldn't exist
-    else:
-        raise GrokError("Conflicting templates found for name '%s': "
-                        "the inline template in module '%s' conflicts "
-                        "with the file template in directory '%s'" %
-                        (template_name, module_info.dotted_name,
-                         template_dir), None)
-    inline_template_registry.register_inline_template(
-        module_info, template_name, template)
+register_directory = file_template_registry.register_directory
     
-
-def register_directory(template_dir):
-    file_template_registry.register_directory(template_dir)
-
-
-
-    
 all_directory_templates_registries = {}
 
 

Modified: grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.txt
===================================================================
--- grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.txt	2009-07-04 15:23:37 UTC (rev 101546)
+++ grokcore.view/branches/shared_templates_userwarning/src/grokcore/view/templatereg.txt	2009-07-04 16:27:51 UTC (rev 101547)
@@ -14,25 +14,20 @@
 * an action gets registered that gets executed late in configuration
   process that reports on any unassociated templates that are left.
 
-Setup
------
+Registration functions
+----------------------
 
-We create our global template registry once::
+In a normal run of the application, the global registration functions
+are used to register templates. These are ``register_inline_template``
+for inline templates in Python code, and ``register_directory`` for
+templates in directories associated with a module::
 
-  >>> from grokcore.view.templatereg import FileTemplateRegistry
-  >>> reg = FileTemplateRegistry()
+  >>> from grokcore.view.templatereg import (register_directory, 
+  ...                                        register_inline_template)
 
-For testing purposes we will create a directory with two templates in it::
+Setup
+-----
 
-  >>> import os, tempfile
-  >>> template_dir = tempfile.mkdtemp()
-  >>> f = open(os.path.join(template_dir, 'foo.template'), 'w')
-  >>> f.write('foo')
-  >>> f.close()
-  >>> f = open(os.path.join(template_dir, 'bar.template'), 'w')
-  >>> f.write('bar')
-  >>> f.close()
-
 Our templates are ``.template``, so we need to register a
 ``ITemplateFileFactory`` utility for them that knows how to make the
 appropriate templates::
@@ -64,22 +59,50 @@
   >>> component.provideUtility(TestTemplateFactory(), ITemplateFileFactory, 
   ...   name='template')
 
-Registration functions
-----------------------
+We create a way to create a fake module_info for a (actually
+nonexistent) module with a real directory that contains templates::
 
-Below we are going to manually create and test template registries. In
-a normal run of the application, the global registration functions are
-used to register templates. These are ``register_inline_template`` for
-inline templates in Python code, and ``register_directory`` for
-templates in directories.
+   >>> class ModuleInfo(object):
+   ...     def __init__(self, name, dir):
+   ...         self.dotted_name = name
+   ...         self.name = name
+   ...         self.dir = dir
+   ...     def getModule(self):
+   ...         return None
+   ...     def getResourcePath(self, template_dir_name):
+   ...         return os.path.join(self.dir, template_dir_name)
+   ...     def isPackage(self):
+   ...         return False
 
+   >>> import os, tempfile
+   >>> def create_module_info_with_templates(module_name):
+   ...     package_dir = tempfile.mkdtemp()
+   ...     templates_dir = os.path.join(package_dir, module_name + '_templates')
+   ...     os.mkdir(templates_dir)
+   ...     return ModuleInfo(module_name, package_dir), templates_dir
+
 Registering a directory
 -----------------------
 
-We can now register the filesystem templates with the registry::
+We create a directory with two templates in it::
 
-  >>> reg.register_directory(template_dir)
+  >>> module_info, template_dir = create_module_info_with_templates('fake')
+  >>> f = open(os.path.join(template_dir, 'foo.template'), 'w')
+  >>> f.write('foo')
+  >>> f.close()
+  >>> f = open(os.path.join(template_dir, 'bar.template'), 'w')
+  >>> f.write('bar')
+  >>> f.close()
 
+We can now register the filesystem templates associated with our
+module_info with the registry::
+
+  >>> register_directory(module_info)
+
+We'll also import the global template registry to do some checks::
+
+  >>> from grokcore.view.templatereg import file_template_registry as reg
+
 We can look up the templates in the registry now::
 
   >>> reg.lookup(template_dir, 'foo')
@@ -88,19 +111,19 @@
   <Template 'bar.template' in '...'>
 
 If we try to look up a template in a directory that doesn't exist, we get
-a LookupError::
+a TemplateLookupError::
   
   >>> reg.lookup('certainlydoesntexist', 'foo')
   Traceback (most recent call last):
     ...
-  LookupError: template 'foo' in 'certainlydoesntexist' cannot be found
+  TemplateLookupError: template 'foo' in 'certainlydoesntexist' cannot be found
 
 We get this error for templates that do not exist as well::
 
   >>> reg.lookup(template_dir, 'doesntexist')
   Traceback (most recent call last):
     ...
-  LookupError: template 'doesntexist' in ... cannot be found
+  TemplateLookupError: template 'doesntexist' in ... cannot be found
 
 Since no templates have yet been associated, retrieving the unassociated
 templates will get us all registered templates::
@@ -124,7 +147,7 @@
 the system::
 
   >>> import os, tempfile
-  >>> template_dir2 = tempfile.mkdtemp()
+  >>> module_info2, template_dir2 = create_module_info_with_templates('module2')
   >>> f = open(os.path.join(template_dir2, 'foo.unknown'), 'w')
   >>> f.write('unknown')
   >>> f.close()
@@ -139,7 +162,7 @@
 
 We register the directory now, and we get the warning::
 
-  >>> reg.register_directory(template_dir2)
+  >>> reg.register_directory(module_info2)
   From grok.testing's warn():
   ... UserWarning: File 'foo.unknown' has an unrecognized extension in directory '...'
   ...
@@ -153,7 +176,7 @@
   >>> reg.lookup(template_dir2, 'foo.unknown')
   Traceback (most recent call last):
     ...
-  LookupError: template 'foo.unknown' in '...' cannot be found
+  TemplateLookupError: template 'foo.unknown' in '...' cannot be found
 
 Multiple templates with the same name
 -------------------------------------
@@ -169,8 +192,7 @@
 templates have the same name but use different template languages, and
 Grok won't know which one it should use::
 
-  >>> import os, tempfile
-  >>> template_dir3 = tempfile.mkdtemp()
+  >>> module_info3, template_dir3 = create_module_info_with_templates('module3')
   >>> f = open(os.path.join(template_dir3, 'foo.1'), 'w')
   >>> f.write('1')
   >>> f.close()
@@ -180,7 +202,7 @@
 
 We expect an error when we register this directory::
 
-  >>> reg.register_directory(template_dir3)
+  >>> register_directory(module_info3)
   Traceback (most recent call last):
     ...
   GrokError: Conflicting templates found for name 'foo' in directory '...': 
@@ -192,24 +214,6 @@
 Inline templates are defined in a Python module instead of on the
 filesystem.
 
-First we create a fake ModuleInfo class:
-
-   >>> class ModuleInfo(object):
-   ...     dotted_name = 'module'
-   ...     name = 'module'
-   ...     def __init__(self, dotted_name, name, dir):
-   ...         self.dotted_name = dotted_name
-   ...         self.name = name
-   ...         self.dir = dir
-   ...     def getModule(self):
-   ...         return None
-   ...     def getResourcePath(self, template_dir_name):
-   ...         return os.path.join(self.dir, template_dir_name)
-
-an create an instance of this class::
-
-   >>> module_info = ModuleInfo('module', 'module', None)
-
 Let's create a class for inline template and create an instance::
 
   >>> class InlineTemplate(object):
@@ -219,73 +223,87 @@
   ...         return "<InlineTemplate '%s'>" % self.name
   >>> cavepainting = InlineTemplate('cavepainting')
 
-We create our global inline template registry once::
+Let's register an inline template with the registry::
 
-  >>> from grokcore.view.templatereg import InlineTemplateRegistry
-  >>> inline_reg = InlineTemplateRegistry()
+  >>> module_info4, template_dir4 = create_module_info_with_templates('module4')
+  >>> register_inline_template(module_info4, 'cavepainting', cavepainting)
 
-Let's register an inline template with the registry::
+  >>> from grokcore.view.templatereg import inline_template_registry as inline_reg
 
-  >>> inline_reg.register_inline_template(module_info, 'cavepainting', cavepainting)
-
 We can look it up now::
 
-  >>> inline_reg.lookup(module_info, 'cavepainting')
+  >>> inline_reg.lookup(module_info4, 'cavepainting')
   <InlineTemplate 'cavepainting'>
   
 If we cannot find the template we get an error::
 
-  >>> inline_reg.lookup(module_info, 'unknown')
+  >>> inline_reg.lookup(module_info4, 'unknown')
   Traceback (most recent call last):
     ...
-  LookupError: inline template 'unknown' in 'module' cannot be found
+  TemplateLookupError: inline template 'unknown' in 'module4' cannot be found
 
 Since no templates have yet been associated, retrieving the
 unassociated templates will get us all registered inline templates::
 
   >>> sorted(inline_reg.unassociated())
-  [('module', 'cavepainting')]
+  [('module4', 'cavepainting')]
 
 Conflicts between inline templates and file templates
 -----------------------------------------------------
 
-
 We construct a fake templates directory that's associated with the fictional
 ``module`` module::
 
   >>> import os, tempfile
-  >>> package_dir = tempfile.mkdtemp()
-  >>> module_template_dir = os.path.join(package_dir, 'module_templates')
-  >>> os.mkdir(module_template_dir)
 
-And we create the module info for this::
+  >>> module_info5, template_dir5 = create_module_info_with_templates('module5')
 
-   >>> module_info = ModuleInfo('module', 'module', package_dir)
-
 We create a template with the name ``foo`` in it::
 
-  >>> f = open(os.path.join(module_template_dir, 'foo.template'), 'w')
+  >>> f = open(os.path.join(template_dir5, 'foo.template'), 'w')
   >>> f.write('foo')
   >>> f.close()
 
 We register this directory, using the global registration functionality::
 
-  >>> from grokcore.view.templatereg import register_directory
-  >>> register_directory(module_template_dir)
+  >>> register_directory(module_info5)
 
 We now also try to register an inline template with the same name
 (``foo``), but this fails due to a conflict with the file template::
 
-  >>> from grokcore.view.templatereg import register_inline_template
-  >>> register_inline_template(module_info, 'foo', InlineTemplate('foo'))
+  >>> 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 'module' conflicts with the file template in directory 
-  '...module_templates'
+  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 
+``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': 
+   the inline template in module 'module6' conflicts with the file template in directory '...'
+
+
 XXX a common lookup function that looks up both inline or filesystem?



More information about the Checkins mailing list