Browse Source

Fixed #28870 -- Added support for functools.partialmethod serialization in migrations.

Sergey Fedoseev 7 years ago
parent
commit
183fb7b2b9

+ 6 - 3
django/db/migrations/serializer.py

@@ -171,8 +171,11 @@ class FunctoolsPartialSerializer(BaseSerializer):
         imports.update(args_imports)
         imports.update(keywords_imports)
         return (
-            "functools.partial(%s, *%s, **%s)" % (
-                func_string, args_string, keywords_string,
+            'functools.%s(%s, *%s, **%s)' % (
+                self.value.__class__.__name__,
+                func_string,
+                args_string,
+                keywords_string,
             ),
             imports,
         )
@@ -340,7 +343,7 @@ def serializer_factory(value):
         return BaseSimpleSerializer(value)
     if isinstance(value, decimal.Decimal):
         return DecimalSerializer(value)
-    if isinstance(value, functools.partial):
+    if isinstance(value, (functools.partial, functools.partialmethod)):
         return FunctoolsPartialSerializer(value)
     if isinstance(value, (types.FunctionType, types.BuiltinFunctionType, types.MethodType)):
         return FunctionTypeSerializer(value)

+ 1 - 1
docs/releases/2.1.txt

@@ -150,7 +150,7 @@ Management Commands
 Migrations
 ~~~~~~~~~~
 
-* ...
+* Added support for serialization of ``functools.partialmethod`` objects.
 
 Models
 ~~~~~~

+ 6 - 2
docs/topics/migrations.txt

@@ -661,8 +661,8 @@ Django can serialize the following:
 - ``decimal.Decimal`` instances
 - ``enum.Enum`` instances
 - ``uuid.UUID`` instances
-- ``functools.partial`` instances which have serializable ``func``, ``args``,
-  and ``keywords`` values.
+- :func:`functools.partial` and :class:`functools.partialmethod` instances
+  which have serializable ``func``, ``args``, and ``keywords`` values.
 - ``LazyObject`` instances which wrap a serializable value.
 - Any Django field
 - Any function or method reference (e.g. ``datetime.datetime.today``) (must be in module's top-level scope)
@@ -670,6 +670,10 @@ Django can serialize the following:
 - Any class reference (must be in module's top-level scope)
 - Anything with a custom ``deconstruct()`` method (:ref:`see below <custom-deconstruct-method>`)
 
+.. versionchanged:: 2.1
+
+    Serialization support for :class:`functools.partialmethod` was added.
+
 Django cannot serialize:
 
 - Nested classes

+ 8 - 0
tests/migrations/test_writer.py

@@ -520,6 +520,14 @@ class WriterTests(SimpleTestCase):
         self.assertEqual(result.args, value.args)
         self.assertEqual(result.keywords, value.keywords)
 
+    def test_serialize_functools_partialmethod(self):
+        value = functools.partialmethod(datetime.timedelta, 1, seconds=2)
+        result = self.serialize_round_trip(value)
+        self.assertIsInstance(result, functools.partialmethod)
+        self.assertEqual(result.func, value.func)
+        self.assertEqual(result.args, value.args)
+        self.assertEqual(result.keywords, value.keywords)
+
     def test_simple_migration(self):
         """
         Tests serializing a simple migration.