diff --git a/django/utils/functional.py b/django/utils/functional.py index ab0be502ce0..1b81d414faf 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -79,7 +79,7 @@ def lazy(func, *resultclasses): self.__kw = kw if not self.__prepared: self.__prepare_class__() - self.__prepared = True + self.__class__.__prepared = True def __reduce__(self): return ( diff --git a/tests/utils_tests/test_functional.py b/tests/utils_tests/test_functional.py index ab649b79837..af4bd197a6e 100644 --- a/tests/utils_tests/test_functional.py +++ b/tests/utils_tests/test_functional.py @@ -1,3 +1,5 @@ +from unittest import mock + from django.test import SimpleTestCase from django.utils.functional import cached_property, lazy @@ -207,3 +209,12 @@ class FunctionalTests(SimpleTestCase): original_object = b'J\xc3\xbcst a str\xc3\xadng' lazy_obj = lazy(lambda: original_object, bytes) self.assertEqual(repr(original_object), repr(lazy_obj())) + + def test_lazy_class_preparation_caching(self): + # lazy() should prepare the proxy class only once i.e. the first time + # it's used. + lazified = lazy(lambda: 0, int) + __proxy__ = lazified().__class__ + with mock.patch.object(__proxy__, '__prepare_class__') as mocked: + lazified() + mocked.assert_not_called()