changeset 591:a3c011711a30 stable-0.4.x

Ported [704] to 0.4.x branch.
author cmlenz
date Fri, 10 Aug 2007 09:52:13 +0000
parents a8bfe7828ce6
children 6d51c8df5d5a
files ChangeLog genshi/template/loader.py genshi/template/markup.py genshi/template/tests/markup.py
diffstat 4 files changed, 69 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,11 @@
  * Fixed augmented assignment to local variables in Python code blocks.
  * Fixed handling of nested function and class definitions in Python code
    blocks.
+ * Includes were not raising `TemplateNotFound` exceptions even when no
+   fallback has been specified. That has been corrected.
+ * The template loader now raises a `TemplateNotFound` error when a previously
+   cached template is removed or renamed, where it previously was passing up
+   an `OSError`.
 
 
 Version 0.4.3
--- a/genshi/template/loader.py
+++ b/genshi/template/loader.py
@@ -162,7 +162,7 @@
                 if not self.auto_reload or \
                         os.path.getmtime(tmpl.filepath) == self._mtime[filename]:
                     return tmpl
-            except KeyError:
+            except KeyError, OSError:
                 pass
 
             search_path = self.search_path
--- a/genshi/template/markup.py
+++ b/genshi/template/markup.py
@@ -83,8 +83,8 @@
         dirmap = {} # temporary mapping of directives to elements
         ns_prefix = {}
         depth = 0
-        in_fallback = 0
-        include_href = None
+        fallbacks = []
+        includes = []
 
         if not isinstance(source, Stream):
             source = XMLParser(source, filename=self.filename,
@@ -154,9 +154,11 @@
                             raise TemplateSyntaxError('Include misses required '
                                                       'attribute "href"',
                                                       self.filepath, *pos[1:])
+                        includes.append(include_href)
                         streams.append([])
                     elif tag.localname == 'fallback':
-                        in_fallback += 1
+                        streams.append([])
+                        fallbacks.append(streams[-1])
 
                 else:
                     stream.append((kind, (tag, new_attrs), pos))
@@ -166,12 +168,16 @@
             elif kind is END:
                 depth -= 1
 
-                if in_fallback and data == self.XINCLUDE_NAMESPACE['fallback']:
-                    in_fallback -= 1
+                if fallbacks and data == self.XINCLUDE_NAMESPACE['fallback']:
+                    assert streams.pop() is fallbacks[-1]
                 elif data == self.XINCLUDE_NAMESPACE['include']:
-                    fallback = streams.pop()
+                    fallback = None
+                    if len(fallbacks) == len(includes):
+                        fallback = fallbacks.pop()
+                    streams.pop() # discard anything between the include tags
+                                  # and the fallback element
                     stream = streams[-1]
-                    stream.append((INCLUDE, (include_href, fallback), pos))
+                    stream.append((INCLUDE, (includes.pop(), fallback), pos))
                 else:
                     stream.append((kind, data, pos))
 
@@ -225,7 +231,7 @@
 
     def _prepare(self, stream):
         for kind, data, pos in Template._prepare(self, stream):
-            if kind is INCLUDE:
+            if kind is INCLUDE and data[1]:
                 data = data[0], list(self._prepare(data[1]))
             yield kind, data, pos
 
--- a/genshi/template/tests/markup.py
+++ b/genshi/template/tests/markup.py
@@ -22,7 +22,7 @@
 from genshi.core import Markup
 from genshi.input import XML
 from genshi.template.base import BadDirectiveError, TemplateSyntaxError
-from genshi.template.loader import TemplateLoader
+from genshi.template.loader import TemplateLoader, TemplateNotFound
 from genshi.template.markup import MarkupTemplate
 
 
@@ -351,6 +351,23 @@
         finally:
             shutil.rmtree(dirname)
 
+    def test_error_when_include_not_found(self):
+        dirname = tempfile.mkdtemp(suffix='genshi_test')
+        try:
+            file2 = open(os.path.join(dirname, 'tmpl2.html'), 'w')
+            try:
+                file2.write("""<html xmlns:xi="http://www.w3.org/2001/XInclude">
+                  <xi:include href="tmpl1.html"/>
+                </html>""")
+            finally:
+                file2.close()
+
+            loader = TemplateLoader([dirname], auto_reload=True)
+            tmpl = loader.load('tmpl2.html')
+            self.assertRaises(TemplateNotFound, tmpl.generate().render)
+        finally:
+            shutil.rmtree(dirname)
+
     def test_fallback_when_include_not_found(self):
         dirname = tempfile.mkdtemp(suffix='genshi_test')
         try:
@@ -397,7 +414,7 @@
             loader = TemplateLoader([dirname])
             tmpl = loader.load('tmpl3.html')
             self.assertEqual("""<html>
-                  <div>Included</div>
+                      <div>Included</div>
                 </html>""", tmpl.generate().render())
         finally:
             shutil.rmtree(dirname)
@@ -422,7 +439,36 @@
             loader = TemplateLoader([dirname])
             tmpl = loader.load('tmpl3.html')
             self.assertEqual("""<html>
-                        Missing
+                      Missing
+                </html>""", tmpl.generate().render())
+        finally:
+            shutil.rmtree(dirname)
+
+    def test_nested_include_in_fallback(self):
+        dirname = tempfile.mkdtemp(suffix='genshi_test')
+        try:
+            file1 = open(os.path.join(dirname, 'tmpl2.html'), 'w')
+            try:
+                file1.write("""<div>Included</div>""")
+            finally:
+                file1.close()
+
+            file2 = open(os.path.join(dirname, 'tmpl3.html'), 'w')
+            try:
+                file2.write("""<html xmlns:xi="http://www.w3.org/2001/XInclude">
+                  <xi:include href="tmpl2.html">
+                    <xi:fallback>
+                      <xi:include href="tmpl1.html" />
+                    </xi:fallback>
+                  </xi:include>
+                </html>""")
+            finally:
+                file2.close()
+
+            loader = TemplateLoader([dirname])
+            tmpl = loader.load('tmpl3.html')
+            self.assertEqual("""<html>
+                  <div>Included</div>
                 </html>""", tmpl.generate().render())
         finally:
             shutil.rmtree(dirname)
Copyright (C) 2012-2017 Edgewall Software