Fixed #34822 -- Added support for serializing functions decorated with functools.lru_cache in migrations.

`@functools.cache` and `@functools.lru_cache` return an object of type
`functools._lru_cache_wrapper` which prevented the migrations serializer from
working. Simply using the existing `FunctionTypeSerializer` for this additional
type works as expected.
This commit is contained in:
Nick Pope 2023-09-13 15:49:10 +01:00 committed by Natalia
parent c131949e3e
commit f92e68c30a
4 changed files with 23 additions and 1 deletions

View File

@ -350,6 +350,7 @@ class Serializer:
types.FunctionType,
types.BuiltinFunctionType,
types.MethodType,
functools._lru_cache_wrapper,
): FunctionTypeSerializer,
collections.abc.Iterable: IterableSerializer,
(COMPILED_REGEX_TYPE, RegexObject): RegexSerializer,

View File

@ -401,7 +401,9 @@ Management Commands
Migrations
~~~~~~~~~~
* ...
* Serialization of functions decorated with :func:`functools.cache` or
:func:`functools.lru_cache` is now supported without the need to write a
custom serializer.
Models
~~~~~~

View File

@ -788,6 +788,8 @@ Django can serialize the following:
- Functions may be decorated if wrapped properly, i.e. using
:func:`functools.wraps`
- The :func:`functools.cache` and :func:`functools.lru_cache` decorators are
explicitly supported
- Unbound methods used from within the class body
- Any class reference (must be in module's top-level scope)
@ -797,6 +799,11 @@ Django can serialize the following:
Serialization support for ``enum.Flag`` was added.
.. versionchanged:: 5.0
Serialization support for functions decorated with :func:`functools.cache`
or :func:`functools.lru_cache` was added.
Django cannot serialize:
- Nested classes

View File

@ -90,6 +90,16 @@ def function_with_decorator():
pass
@functools.cache
def function_with_cache():
pass
@functools.lru_cache(maxsize=10)
def function_with_lru_cache():
pass
class OperationWriterTests(SimpleTestCase):
def test_empty_signature(self):
operation = custom_migration_operations.operations.TestOperation()
@ -581,6 +591,8 @@ class WriterTests(SimpleTestCase):
def test_serialize_decorated_functions(self):
self.assertSerializedEqual(function_with_decorator)
self.assertSerializedEqual(function_with_cache)
self.assertSerializedEqual(function_with_lru_cache)
def test_serialize_datetime(self):
self.assertSerializedEqual(datetime.datetime.now())