]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
AttributeError in undefined message doesn't cause RuntimeError 1179/head
authorDavid Lord <davidism@gmail.com>
Fri, 27 Mar 2020 16:51:53 +0000 (09:51 -0700)
committerDavid Lord <davidism@gmail.com>
Fri, 27 Mar 2020 16:51:53 +0000 (09:51 -0700)
CHANGES.rst
src/jinja2/utils.py
tests/test_api.py

index aee6ad3a3e9193b2e542b1fe7d9b3da296a47a8c..0902830b30be7563bbf7f0ad86ada262eb925527 100644 (file)
@@ -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
index e3285e8edb45daf70b7612d8ad256f29ff09f456..94581ca855d973d473a0fffb861f369537bf7f9e 100644 (file)
@@ -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
 
 
index 058ec56cb9941dbcc9965dd31bf4b8e798db15b7..7a1cae866b011b29ada2abc593aa7d58093760c0 100644 (file)
@@ -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 = []