From 2d0252ef417635ce2318a9015bafa916fd850ed6 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Fri, 4 Feb 2011 17:21:10 +0000 Subject: [PATCH] [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. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15414 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 1 + django/template/loader_tags.py | 4 +- .../templates/templatetags/bad_tag.py | 7 +++ .../templates/templatetags/broken_tag.py | 2 +- tests/regressiontests/templates/tests.py | 53 +++++++++++++------ 5 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 tests/regressiontests/templates/templatetags/bad_tag.py diff --git a/AUTHORS b/AUTHORS index 220fe45d9d..3656e92a42 100644 --- a/AUTHORS +++ b/AUTHORS @@ -250,6 +250,7 @@ answer newbie questions, and generally made Django that much better: Bahadır Kandemir Karderio Nagy Károly + George Karpenkov Erik Karulf Ben Dean Kawamura Ian G. Kelly diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py index b8bc741d41..ba06805cb6 100644 --- a/django/template/loader_tags.py +++ b/django/template/loader_tags.py @@ -149,12 +149,10 @@ class IncludeNode(Node): 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): """ diff --git a/tests/regressiontests/templates/templatetags/bad_tag.py b/tests/regressiontests/templates/templatetags/bad_tag.py new file mode 100644 index 0000000000..86c275bb05 --- /dev/null +++ b/tests/regressiontests/templates/templatetags/bad_tag.py @@ -0,0 +1,7 @@ +from django import template + +register = template.Library() + +@register.tag +def badtag(parser, token): + raise RuntimeError("I am a bad tag") diff --git a/tests/regressiontests/templates/templatetags/broken_tag.py b/tests/regressiontests/templates/templatetags/broken_tag.py index c70e183f0e..d69ddaeb2c 100644 --- a/tests/regressiontests/templates/templatetags/broken_tag.py +++ b/tests/regressiontests/templates/templatetags/broken_tag.py @@ -1 +1 @@ -from django import Xtemplate +from django import Xtemplate \ No newline at end of file diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 2f198b61ce..7a3de22f57 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -353,46 +353,58 @@ class Templates(unittest.TestCase): 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]: @@ -573,7 +585,7 @@ class Templates(unittest.TestCase): # 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'), @@ -642,7 +654,7 @@ class Templates(unittest.TestCase): ### 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)), @@ -911,10 +923,19 @@ class Templates(unittest.TestCase): '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 @@ -1124,8 +1145,8 @@ class Templates(unittest.TestCase): '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 ############################################################# @@ -1258,8 +1279,8 @@ class Templates(unittest.TestCase): # 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),