Skip to content

Commit

Permalink
Improved error message for undefineds
Browse files Browse the repository at this point in the history
--HG--
branch : trunk
  • Loading branch information
mitsuhiko committed Apr 12, 2010
1 parent 7d29ec6 commit 98dbf5f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
13 changes: 7 additions & 6 deletions jinja2/runtime.py
Expand Up @@ -12,7 +12,8 @@
from itertools import chain, imap
from jinja2.nodes import EvalContext
from jinja2.utils import Markup, partial, soft_unicode, escape, missing, \
concat, MethodType, FunctionType, internalcode, next
concat, MethodType, FunctionType, internalcode, next, \
object_type_repr
from jinja2.exceptions import UndefinedError, TemplateRuntimeError, \
TemplateNotFound

Expand Down Expand Up @@ -437,13 +438,13 @@ def _fail_with_undefined_error(self, *args, **kwargs):
if self._undefined_obj is missing:
hint = '%r is undefined' % self._undefined_name
elif not isinstance(self._undefined_name, basestring):
hint = '%r object has no element %r' % (
self._undefined_obj.__class__.__name__,
hint = '%s has no element %r' % (
object_type_repr(self._undefined_obj),
self._undefined_name
)
else:
hint = '%r object has no attribute %r' % (
self._undefined_obj.__class__.__name__,
hint = '%r has no attribute %r' % (
object_type_repr(self._undefined_obj),
self._undefined_name
)
else:
Expand Down Expand Up @@ -501,7 +502,7 @@ def __unicode__(self):
if self._undefined_obj is missing:
return u'{{ %s }}' % self._undefined_name
return '{{ no such element: %s[%r] }}' % (
self._undefined_obj.__class__.__name__,
object_type_repr(self._undefined_obj),
self._undefined_name
)
return u'{{ undefined value printed: %s }}' % self._undefined_hint
Expand Down
14 changes: 11 additions & 3 deletions jinja2/testsuite/api.py
Expand Up @@ -207,11 +207,19 @@ def test_indexing_gives_undefined(self):
t = Template("{{ var[42].foo }}")
assert_raises(UndefinedError, t.render, var=0)

def test_none_gives_propert_error(self):
def test_none_gives_proper_error(self):
try:
Undefined(None).split()
Environment().getattr(None, 'split')
except UndefinedError, e:
assert e.message == 'None is not defined'
assert e.message == "None has no attribute 'split'"
else:
assert False, 'expected exception'

def test_object_repr(self):
try:
Undefined(obj=42, name='upper')
except UndefinedError, e:
assert e.message == "'int' object has no attribute 'upper'"
else:
assert False, 'expected exception'

Expand Down
16 changes: 16 additions & 0 deletions jinja2/utils.py
Expand Up @@ -227,6 +227,22 @@ def open_if_exists(filename, mode='rb'):
raise


def object_type_repr(obj):
"""Returns the name of the object's type. For some recognized
singletons the name of the object is returned instead. (For
example for `None` and `Ellipsis`).
"""
if obj is None:
return 'None'
elif obj is Ellipsis:
return 'Ellipsis'
if obj.__class__.__module__ == '__builtin__':
name = obj.__name__
else:
name = obj.__class__.module__ + '.' + obj.__name__
return '%s object' % name


def pformat(obj, verbose=False):
"""Prettyprint an object. Either use the `pretty` library or the
builtin `pprint`.
Expand Down

0 comments on commit 98dbf5f

Please sign in to comment.