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:
parent
e4fb3982a1
commit
58f61e0373
|
@ -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"
|
||||
|
|
|
@ -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])]
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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"),
|
||||
|
|
Loading…
Reference in New Issue