# HG changeset patch # User cmlenz # Date 1186739533 0 # Node ID bb81418988918203b1ccdaf3ca8ecb74fa33e433 # Parent 3cb55344d62fd161ede03eec520ba17c595904d5 Ported [704] to 0.4.x branch. diff --git a/ChangeLog b/ChangeLog --- 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 diff --git a/genshi/template/loader.py b/genshi/template/loader.py --- 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 diff --git a/genshi/template/markup.py b/genshi/template/markup.py --- 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 diff --git a/genshi/template/tests/markup.py b/genshi/template/tests/markup.py --- 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(""" + + """) + 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(""" -
Included
+
Included
""", tmpl.generate().render()) finally: shutil.rmtree(dirname) @@ -422,7 +439,36 @@ loader = TemplateLoader([dirname]) tmpl = loader.load('tmpl3.html') self.assertEqual(""" - Missing + Missing + """, 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("""
Included
""") + finally: + file1.close() + + file2 = open(os.path.join(dirname, 'tmpl3.html'), 'w') + try: + file2.write(""" + + + + + + """) + finally: + file2.close() + + loader = TemplateLoader([dirname]) + tmpl = loader.load('tmpl3.html') + self.assertEqual(""" +
Included
""", tmpl.generate().render()) finally: shutil.rmtree(dirname)