1
0
mirror of https://github.com/django/django.git synced 2025-10-23 21:59:11 +00:00

Made proxy class in lazy() prepare eagerly.

Previously, the proxy class was prepared lazily:

  lazy_identity = lazy(identity, int)
  lazy_identity(10)  # prepared here
  lazy_identity(10)

This has a slight advantage that if the lazy doesn't end up getting
used, the preparation work is skipped, however that's not very likely.

Besides this laziness, it is also inconsistent in that the methods which
are wrapped directly (__str__ etc.) are prepared already when __proxy__
is defined, and there is a weird half-initialized state.

This change it so that everything is prepared already on the first line
of the example above.
This commit is contained in:
Ran Benita
2020-04-26 21:42:07 +03:00
committed by Mariusz Felisiak
parent b214845f0f
commit ae94077e7d
2 changed files with 30 additions and 44 deletions

View File

@@ -1,5 +1,3 @@
from unittest import mock
from django.test import SimpleTestCase
from django.utils.functional import cached_property, classproperty, lazy
from django.utils.version import PY312
@@ -273,14 +271,10 @@ class FunctionalTests(SimpleTestCase):
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()
def test_lazy_regular_method(self):
original_object = 15
lazy_obj = lazy(lambda: original_object, int)
self.assertEqual(original_object.bit_length(), lazy_obj().bit_length())
def test_lazy_bytes_and_str_result_classes(self):
lazy_obj = lazy(lambda: "test", str, bytes)