diff --git a/django/utils/functional.py b/django/utils/functional.py index 8dd8a8e006..5827389231 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -288,6 +288,9 @@ class LazyObject: self._wrapped = empty def __getattribute__(self, name): + if name == "_wrapped": + # Avoid recursion when getting wrapped object. + return super().__getattribute__(name) value = super().__getattribute__(name) # If attribute is a proxy method, raise an AttributeError to call # __getattr__() and use the wrapped object method. diff --git a/tests/utils_tests/test_lazyobject.py b/tests/utils_tests/test_lazyobject.py index 161c9dbcec..134ae77750 100644 --- a/tests/utils_tests/test_lazyobject.py +++ b/tests/utils_tests/test_lazyobject.py @@ -58,6 +58,14 @@ class LazyObjectTestCase(TestCase): obj = self.lazy_wrap(Foo()) self.assertEqual(obj.foo, "bar") + def test_getattr_falsey(self): + class Thing: + def __getattr__(self, key): + return [] + + obj = self.lazy_wrap(Thing()) + self.assertEqual(obj.main, []) + def test_setattr(self): obj = self.lazy_wrap(Foo()) obj.foo = "BAR"