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
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:
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
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'
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`.