From 28a571348bca9c5a3c137e495e7d3c9349a5bd56 Mon Sep 17 00:00:00 2001 From: Baptiste Mispelon Date: Sun, 8 Sep 2013 15:07:12 +0200 Subject: [PATCH] Fix #20745: Don't silence TypeError raised inside templates. Thanks to robin for the report and claudep for the review. --- django/template/base.py | 13 ++++++++----- docs/releases/1.7.txt | 3 +++ tests/template_tests/tests.py | 6 ++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/django/template/base.py b/django/template/base.py index 1f3c2503621..9e3ea0f3c64 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import re from functools import partial from importlib import import_module -from inspect import getargspec +from inspect import getargspec, getcallargs from django.conf import settings from django.template.context import (BaseContext, Context, RequestContext, @@ -788,10 +788,13 @@ class Variable(object): else: try: # method call (assuming no args required) current = current() - except TypeError: # arguments *were* required - # GOTCHA: This will also catch any TypeError - # raised in the function itself. - current = settings.TEMPLATE_STRING_IF_INVALID # invalid method call + except TypeError: + try: + getcallargs(current) + except TypeError: # arguments *were* required + current = settings.TEMPLATE_STRING_IF_INVALID # invalid method call + else: + raise except Exception as e: if getattr(e, 'silent_variable_failure', False): current = settings.TEMPLATE_STRING_IF_INVALID diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt index 120ec4c18ad..d6c9dc4b5c7 100644 --- a/docs/releases/1.7.txt +++ b/docs/releases/1.7.txt @@ -282,6 +282,9 @@ Templates :setting:`TEMPLATE_DEBUG` is ``True``. This allows template origins to be inspected and logged outside of the ``django.template`` infrastructure. +* ``TypeError`` exceptions are not longer silenced when raised during the + rendering of a template. + Backwards incompatible changes in 1.7 ===================================== diff --git a/tests/template_tests/tests.py b/tests/template_tests/tests.py index cf294c2280d..7fb194fe38d 100644 --- a/tests/template_tests/tests.py +++ b/tests/template_tests/tests.py @@ -98,6 +98,9 @@ class SomeClass: def method4(self): raise SomeOtherException + def method5(self): + raise TypeError + def __getitem__(self, key): if key == 'silent_fail_key': raise SomeException @@ -680,6 +683,9 @@ class TemplateTests(TransRealMixin, TestCase): # Fail silently when accessing a non-simple method 'basic-syntax20': ("{{ var.method2 }}", {"var": SomeClass()}, ("","INVALID")), + # Don't silence a TypeError if it was raised inside a callable + 'basic-syntax20b': ("{{ var.method5 }}", {"var": SomeClass()}, TypeError), + # Don't get confused when parsing something that is almost, but not # quite, a template tag. 'basic-syntax21': ("a {{ moo %} b", {}, "a {{ moo %} b"),