changeset 590:880b1a75d046

Fix includes so that they again raise an exception when the included template is not found and no fallback has been provided.
author cmlenz
date Fri, 10 Aug 2007 09:44:00 +0000
parents c079c5c4f6f4
children 7145e4eba2ec
files ChangeLog genshi/template/base.py genshi/template/loader.py genshi/template/markup.py genshi/template/tests/markup.py
diffstat 5 files changed, 69 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -26,6 +26,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/base.py
+++ b/genshi/template/base.py
@@ -392,7 +392,7 @@
                             for event in self._prepare(fallback):
                                 yield event
                         continue
-                    else:
+                    elif fallback:
                         # Otherwise the include is performed at run time
                         data = href, list(self._prepare(fallback))
 
--- a/genshi/template/loader.py
+++ b/genshi/template/loader.py
@@ -174,7 +174,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,
@@ -155,9 +155,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))
@@ -167,12 +169,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))
 
--- 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