From: David Lord Date: Fri, 27 Mar 2020 16:51:53 +0000 (-0700) Subject: AttributeError in undefined message doesn't cause RuntimeError X-Git-Tag: 2.11.2~7^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f15452f130b82090ca1e1f650b5b7662496633db;p=thirdparty%2Fjinja.git AttributeError in undefined message doesn't cause RuntimeError --- diff --git a/CHANGES.rst b/CHANGES.rst index aee6ad3a..0902830b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,6 +12,9 @@ Unreleased by wrapping the input in :func:`soft_unicode`. :pr:`1160` - Fix a hang when displaying tracebacks on Python 32-bit. :issue:`1162` +- Showing an undefined error for an object that raises + ``AttributeError`` on access doesn't cause a recursion error. + :issue:`1177` Version 2.11.1 diff --git a/src/jinja2/utils.py b/src/jinja2/utils.py index e3285e8e..94581ca8 100644 --- a/src/jinja2/utils.py +++ b/src/jinja2/utils.py @@ -165,11 +165,15 @@ def object_type_repr(obj): return "None" elif obj is Ellipsis: return "Ellipsis" + + cls = type(obj) + # __builtin__ in 2.x, builtins in 3.x - if obj.__class__.__module__ in ("__builtin__", "builtins"): - name = obj.__class__.__name__ + if cls.__module__ in ("__builtin__", "builtins"): + name = cls.__name__ else: - name = obj.__class__.__module__ + "." + obj.__class__.__name__ + name = cls.__module__ + "." + cls.__name__ + return "%s object" % name diff --git a/tests/test_api.py b/tests/test_api.py index 058ec56c..7a1cae86 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -269,6 +269,21 @@ class TestUndefined(object): with pytest.raises(AttributeError): Undefined("Foo").__dict__ + def test_undefined_attribute_error(self): + # Django's LazyObject turns the __class__ attribute into a + # property that resolves the wrapped function. If that wrapped + # function raises an AttributeError, printing the repr of the + # object in the undefined message would cause a RecursionError. + class Error(object): + @property + def __class__(self): + raise AttributeError() + + u = Undefined(obj=Error(), name="hello") + + with pytest.raises(UndefinedError): + getattr(u, "recursion", None) + def test_logging_undefined(self): _messages = []