Browse Source

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`.
Nick Pope 1 year ago
parent
commit
e042024b28
2 changed files with 14 additions and 0 deletions
  1. 3 0
      django/utils/functional.py
  2. 11 0
      tests/utils_tests/test_functional.py

+ 3 - 0
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.
 

+ 11 - 0
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.