magic-removal: Removed SilentVariableFailure exception, in favor of a silent_variable_failure attribute on the exception. Updated docs and added unit tests.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1680 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2005-12-16 01:58:03 +00:00
parent e4fb3982a1
commit 58f61e0373
4 changed files with 40 additions and 18 deletions

View File

@ -1,13 +1,11 @@
"Global Django exceptions"
from django.core.template import SilentVariableFailure
class Http404(Exception):
pass
class ObjectDoesNotExist(SilentVariableFailure):
class ObjectDoesNotExist(Exception):
"The requested object does not exist"
pass
silent_variable_failure = True
class SuspiciousOperation(Exception):
"The user did something suspicious"

View File

@ -102,10 +102,6 @@ class TemplateDoesNotExist(Exception):
class VariableDoesNotExist(Exception):
pass
class SilentVariableFailure(Exception):
"Any function raising this exception will be ignored by resolve_variable"
pass
class InvalidTemplateLibrary(Exception):
pass
@ -662,12 +658,15 @@ def resolve_variable(path, context):
else:
try: # method call (assuming no args required)
current = current()
except SilentVariableFailure:
current = ''
except TypeError: # arguments *were* required
# GOTCHA: This will also catch any TypeError
# raised in the function itself.
current = '' # invalid method call
except Exception, e:
if getattr(e, 'silent_variable_failure', False):
current = ''
else:
raise
except (TypeError, AttributeError):
try: # list-index lookup
current = current[int(bits[0])]

View File

@ -147,10 +147,10 @@ Method lookups are slightly more complex than the other lookup types. Here are
some things to keep in mind:
* If, during the method lookup, a method raises an exception, the exception
will be propagated, unless the exception subclasses
``django.core.template.SilentVariableFailure``. If the exception
subclasses ``SilentVariableFailure``, the variable will render as an
empty string. Example::
will be propagated, unless the exception has an attribute
``silent_variable_failure`` whose value is ``True``. If the exception
*does* have a ``silent_variable_failure`` attribute, the variable will
render as an empty string. Example::
>>> t = Template("My name is {{ person.first_name }}.")
>>> class PersonClass3:
@ -162,15 +162,21 @@ some things to keep in mind:
...
AssertionError: foo
>>> from django.core.template import SilentVariableFailure
>>> class SilentAssertionError(SilentVariableFailure): pass
>>> class SilentAssertionError(Exception):
... silent_variable_failure = True
>>> class PersonClass4:
... def first_name(self):
... raise SilentAssertionError, "foo"
... raise SilentAssertionError
>>> p = PersonClass4()
>>> t.render(Context({"person": p}))
"My name is ."
Note that ``django.core.exceptions.ObjectDoesNotExist``, which is the
base class for all Django database API ``DoesNotExist`` exceptions, has
``silent_variable_failure = True``. So if you're using Django templates
with Django model objects, any ``DoesNotExist`` exception will fail
silently.
* A method call will only work if the method has no required arguments.
Otherwise, the system will move to the next lookup type (list-index
lookup).

View File

@ -32,6 +32,12 @@ template.libraries['django.templatetags.testtags'] = register
# Helper objects for template tests #
#####################################
class SomeException(Exception):
silent_variable_failure = True
class SomeOtherException(Exception):
pass
class SomeClass:
def __init__(self):
self.otherclass = OtherClass()
@ -42,6 +48,12 @@ class SomeClass:
def method2(self, o):
return o
def method3(self):
raise SomeException
def method4(self):
raise SomeOtherException
class OtherClass:
def method(self):
return "OtherClass.method"
@ -133,7 +145,14 @@ TEMPLATE_TESTS = {
'basic-syntax31': (r'{{ var|default_if_none:var2 }}', {"var": None, "var2": "happy"}, 'happy'),
# Default argument testing
'basic-syntax32' : (r'{{ var|yesno:"yup,nup,mup" }} {{ var|yesno }}', {"var": True}, 'yup yes'),
'basic-syntax32': (r'{{ var|yesno:"yup,nup,mup" }} {{ var|yesno }}', {"var": True}, 'yup yes'),
# Fail silently for methods that raise an exception with a "silent_variable_failure" attribute
'basic-syntax33': (r'1{{ var.method3 }}2', {"var": SomeClass()}, "12"),
# In methods that raise an exception without a "silent_variable_attribute" set to True,
# the exception propogates
'basic-syntax34': (r'1{{ var.method4 }}2', {"var": SomeClass()}, SomeOtherException),
### IF TAG ################################################################
'if-tag01': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": True}, "yes"),