From: Armin Ronacher Date: Mon, 12 Apr 2010 13:49:59 +0000 (+0200) Subject: Improved error message for undefineds X-Git-Tag: 2.4~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98dbf5fb1d7fc991d3ccf3f628cd723e8e84d40a;p=thirdparty%2Fjinja.git Improved error message for undefineds --HG-- branch : trunk --- diff --git a/jinja2/runtime.py b/jinja2/runtime.py index 16389e04..1961e9f1 100644 --- a/jinja2/runtime.py +++ b/jinja2/runtime.py @@ -12,7 +12,8 @@ import sys 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 @@ -437,13 +438,13 @@ class Undefined(object): 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: @@ -501,7 +502,7 @@ class DebugUndefined(Undefined): 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 diff --git a/jinja2/testsuite/api.py b/jinja2/testsuite/api.py index 4134d262..dfd8b640 100644 --- a/jinja2/testsuite/api.py +++ b/jinja2/testsuite/api.py @@ -207,11 +207,19 @@ class UndefinedTestCase(JinjaTestCase): 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' diff --git a/jinja2/utils.py b/jinja2/utils.py index 1fd6ec5d..0ba86e76 100644 --- a/jinja2/utils.py +++ b/jinja2/utils.py @@ -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`.