From a2c31e12da272acc76f3a3a0157fae9a7f6477ac Mon Sep 17 00:00:00 2001 From: Ran Benita Date: Fri, 3 May 2019 13:46:21 +0300 Subject: [PATCH] Fixed #30498 -- Fixed proxy class caching in lazy(). lazy() should prepare the proxy class only once (the first time it's used) not on every call. Regression in b4e76f30d12bfa8a53cc297c60055c6f4629cc4c. --- django/utils/functional.py | 2 +- tests/utils_tests/test_functional.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/django/utils/functional.py b/django/utils/functional.py index ab0be502ce..1b81d414fa 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 ab649b7983..af4bd197a6 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()