From e042024b28fcef43606557554714352781fc1d13 Mon Sep 17 00:00:00 2001 From: Nick Pope Date: Wed, 7 Jun 2023 12:34:35 +0100 Subject: [PATCH] Allowed custom formatting of lazy() objects. This allows for formatting of lazy objects which have a custom formatter defined by overriding the default implementation from `object`. --- django/utils/functional.py | 3 +++ tests/utils_tests/test_functional.py | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/django/utils/functional.py b/django/utils/functional.py index 0bc641cb21f..25003204f81 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -151,6 +151,9 @@ def lazy(func, *resultclasses): def __hash__(self): return hash(self.__cast()) + def __format__(self, format_spec): + return format(self.__cast(), format_spec) + # Explicitly wrap methods which are required for certain operations on # int/str objects to function correctly. diff --git a/tests/utils_tests/test_functional.py b/tests/utils_tests/test_functional.py index c8b8fe5a3f6..fa23debb4de 100644 --- a/tests/utils_tests/test_functional.py +++ b/tests/utils_tests/test_functional.py @@ -246,6 +246,17 @@ class FunctionalTests(SimpleTestCase): self.assertEqual(lazy_a() * 5, "aaaaa") self.assertEqual(lazy_a() * lazy_5(), "aaaaa") + def test_lazy_format(self): + class QuotedString(str): + def __format__(self, format_spec): + value = super().__format__(format_spec) + return f"“{value}”" + + lazy_f = lazy(lambda: QuotedString("Hello!"), QuotedString) + self.assertEqual(format(lazy_f(), ""), "“Hello!”") + f = lazy_f() + self.assertEqual(f"I said, {f}", "I said, “Hello!”") + def test_lazy_equality(self): """ == and != work correctly for Promises.