Commits

Anonymous committed 6829478

[1.2.X] Fixed #14046 -- Made {% include %} behave the same, regardless of whether the template included is named by variable or constant string. Thanks to defcube for the report, and George Karpenkov for the draft patch.

Backport of r15413 from trunk.

  • Participants
  • Parent commits 00b85bd
  • Branches releases/1.2.X

Comments (0)

Files changed (5)

     Bahadır Kandemir <bahadir@pardus.org.tr>
     Karderio <karderio@gmail.com>
     Nagy Károly <charlie@rendszergazda.com>
+    George Karpenkov <george@metaworld.ru>
     Erik Karulf <erik@karulf.com>
     Ben Dean Kawamura <ben.dean.kawamura@gmail.com>
     Ian G. Kelly <ian.g.kelly@gmail.com>

django/template/loader_tags.py

             template_name = self.template_name.resolve(context)
             t = get_template(template_name)
             return t.render(context)
-        except TemplateSyntaxError, e:
+        except:
             if settings.TEMPLATE_DEBUG:
                 raise
             return ''
-        except:
-            return '' # Fail silently for invalid included templates.
 
 def do_block(parser, token):
     """

tests/regressiontests/templates/templatetags/bad_tag.py

+from django import template
+
+register = template.Library()
+
+@register.tag
+def badtag(parser, token):
+    raise RuntimeError("I am a bad tag")

tests/regressiontests/templates/templatetags/broken_tag.py

-from django import Xtemplate
+from django import Xtemplate

tests/regressiontests/templates/tests.py

             if isinstance(vals[2], tuple):
                 normal_string_result = vals[2][0]
                 invalid_string_result = vals[2][1]
-                if isinstance(invalid_string_result, basestring) and '%s' in invalid_string_result:
+
+                if isinstance(invalid_string_result, tuple):
                     expected_invalid_str = 'INVALID %s'
-                    invalid_string_result = invalid_string_result % vals[2][2]
+                    invalid_string_result = invalid_string_result[0] % invalid_string_result[1]
                     template.invalid_var_format_string = True
+
+                try:
+                    template_debug_result = vals[2][2]
+                except IndexError:
+                    template_debug_result = normal_string_result
+
             else:
                 normal_string_result = vals[2]
                 invalid_string_result = vals[2]
+                template_debug_result = vals[2]
 
             if 'LANGUAGE_CODE' in vals[1]:
                 activate(vals[1]['LANGUAGE_CODE'])
             else:
                 activate('en-us')
 
-            for invalid_str, result in [('', normal_string_result),
-                                        (expected_invalid_str, invalid_string_result)]:
+            for invalid_str, template_debug, result in [
+                    ('', False, normal_string_result),
+                    (expected_invalid_str, False, invalid_string_result),
+                    ('', True, template_debug_result),
+                ]:
                 settings.TEMPLATE_STRING_IF_INVALID = invalid_str
+                settings.TEMPLATE_DEBUG = template_debug
                 for is_cached in (False, True):
                     try:
                         start = datetime.now()
                         test_template = loader.get_template(name)
                         end = datetime.now()
                         if end-start > timedelta(seconds=0.2):
-                            failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Took too long to parse test" % (is_cached, invalid_str, name))
+                            failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Took too long to parse test" % (is_cached, invalid_str, template_debug, name))
 
                         start = datetime.now()
                         output = self.render(test_template, vals)
                         end = datetime.now()
                         if end-start > timedelta(seconds=0.2):
-                            failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Took too long to render test" % (is_cached, invalid_str, name))
+                            failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Took too long to render test" % (is_cached, invalid_str, template_debug, name))
                     except ContextStackException:
-                        failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Context stack was left imbalanced" % (is_cached, invalid_str, name))
+                        failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Context stack was left imbalanced" % (is_cached, invalid_str, template_debug, name))
                         continue
                     except Exception:
                         exc_type, exc_value, exc_tb = sys.exc_info()
                         if exc_type != result:
                             tb = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_tb))
-                            failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s\n%s" % (is_cached, invalid_str, name, exc_type, exc_value, tb))
+                            failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Got %s, exception: %s\n%s" % (is_cached, invalid_str, template_debug, name, exc_type, exc_value, tb))
                         continue
                     if output != result:
-                        failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Expected %r, got %r" % (is_cached, invalid_str, name, result, output))
+                        failures.append("Template test (Cached='%s', TEMPLATE_STRING_IF_INVALID='%s', TEMPLATE_DEBUG=%s): %s -- FAILED. Expected %r, got %r" % (is_cached, invalid_str, template_debug, name, result, output))
                 cache_loader.reset()
 
             if 'LANGUAGE_CODE' in vals[1]:
 
             # In methods that raise an exception without a
             # "silent_variable_attribute" set to True, the exception propagates
-            'filter-syntax14': (r'1{{ var.method4 }}2', {"var": SomeClass()}, SomeOtherException),
+            'filter-syntax14': (r'1{{ var.method4 }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException, template.TemplateSyntaxError)),
 
             # Escaped backslash in argument
             'filter-syntax15': (r'{{ var|default_if_none:"foo\bar" }}', {"var": None}, r'foo\bar'),
             ### EXCEPTIONS ############################################################
 
             # Raise exception for invalid template name
-            'exception01': ("{% extends 'nonexistent' %}", {}, template.TemplateDoesNotExist),
+            'exception01': ("{% extends 'nonexistent' %}", {}, (template.TemplateDoesNotExist, template.TemplateDoesNotExist, template.TemplateSyntaxError)),
 
             # Raise exception for invalid template name (in variable)
             'exception02': ("{% extends nonexistent %}", {}, (template.TemplateSyntaxError, template.TemplateDoesNotExist)),
             'include01': ('{% include "basic-syntax01" %}', {}, "something cool"),
             'include02': ('{% include "basic-syntax02" %}', {'headline': 'Included'}, "Included"),
             'include03': ('{% include template_name %}', {'template_name': 'basic-syntax02', 'headline': 'Included'}, "Included"),
-            'include04': ('a{% include "nonexistent" %}b', {}, "ab"),
+            'include04': ('a{% include "nonexistent" %}b', {}, ("ab", "ab", template.TemplateDoesNotExist)),
             'include 05': ('template with a space', {}, 'template with a space'),
             'include06': ('{% include "include 05"%}', {}, 'template with a space'),
 
+            ### INCLUSION ERROR REPORTING #############################################
+            'include-fail1': ('{% load bad_tag %}{% badtag %}', {}, RuntimeError),
+            'include-fail2': ('{% load broken_tag %}', {}, template.TemplateSyntaxError),
+            'include-error07': ('{% include "include-fail1" %}', {}, ('', '', RuntimeError)),
+            'include-error08': ('{% include "include-fail2" %}', {}, ('', '', template.TemplateSyntaxError)),
+            'include-error09': ('{% include failed_include %}', {'failed_include': 'include-fail1'}, ('', '', template.TemplateSyntaxError)),
+            'include-error10': ('{% include failed_include %}', {'failed_include': 'include-fail2'}, ('', '', template.TemplateSyntaxError)),
+
+
             ### NAMED ENDBLOCKS #######################################################
 
             # Basic test
             'invalidstr03': ('{% for v in var %}({{ v }}){% endfor %}', {}, ''),
             'invalidstr04': ('{% if var %}Yes{% else %}No{% endif %}', {}, 'No'),
             'invalidstr04': ('{% if var|default:"Foo" %}Yes{% else %}No{% endif %}', {}, 'Yes'),
-            'invalidstr05': ('{{ var }}', {}, ('', 'INVALID %s', 'var')),
-            'invalidstr06': ('{{ var.prop }}', {'var': {}}, ('', 'INVALID %s', 'var.prop')),
+            'invalidstr05': ('{{ var }}', {}, ('', ('INVALID %s', 'var'))),
+            'invalidstr06': ('{{ var.prop }}', {'var': {}}, ('', ('INVALID %s', 'var.prop'))),
 
             ### MULTILINE #############################################################
 
 
             # Failures
             'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
-            'url-fail02': ('{% url no_such_view %}', {}, urlresolvers.NoReverseMatch),
-            'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, urlresolvers.NoReverseMatch),
+            'url-fail02': ('{% url no_such_view %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
+            'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)),
             'url-fail04': ('{% url view id, %}', {}, template.TemplateSyntaxError),
             'url-fail05': ('{% url view id= %}', {}, template.TemplateSyntaxError),
             'url-fail06': ('{% url view a.id=id %}', {}, template.TemplateSyntaxError),