Fixed #26555 -- Gave deconstructible objects a higher priority during serialization

This commit is contained in:
Markus Holtermann 2016-05-04 22:05:11 +02:00
parent 3204bc8e5e
commit 3b383085fb
2 changed files with 34 additions and 11 deletions

View File

@ -329,6 +329,18 @@ def serializer_factory(value):
# tuple. # tuple.
value = value.__reduce__()[1][0] value = value.__reduce__()[1][0]
if isinstance(value, models.Field):
return ModelFieldSerializer(value)
if isinstance(value, models.manager.BaseManager):
return ModelManagerSerializer(value)
if isinstance(value, Operation):
return OperationSerializer(value)
if isinstance(value, type):
return TypeSerializer(value)
# Anything that knows how to deconstruct itself.
if hasattr(value, 'deconstruct'):
return DeconstructableSerializer(value)
# Unfortunately some of these are order-dependent. # Unfortunately some of these are order-dependent.
if isinstance(value, frozenset): if isinstance(value, frozenset):
return FrozensetSerializer(value) return FrozensetSerializer(value)
@ -362,19 +374,8 @@ def serializer_factory(value):
return TextTypeSerializer(value) return TextTypeSerializer(value)
if isinstance(value, decimal.Decimal): if isinstance(value, decimal.Decimal):
return DecimalSerializer(value) return DecimalSerializer(value)
if isinstance(value, models.Field):
return ModelFieldSerializer(value)
if isinstance(value, type):
return TypeSerializer(value)
if isinstance(value, models.manager.BaseManager):
return ModelManagerSerializer(value)
if isinstance(value, Operation):
return OperationSerializer(value)
if isinstance(value, functools.partial): if isinstance(value, functools.partial):
return FunctoolsPartialSerializer(value) return FunctoolsPartialSerializer(value)
# Anything that knows how to deconstruct itself.
if hasattr(value, 'deconstruct'):
return DeconstructableSerializer(value)
if isinstance(value, (types.FunctionType, types.BuiltinFunctionType)): if isinstance(value, (types.FunctionType, types.BuiltinFunctionType)):
return FunctionTypeSerializer(value) return FunctionTypeSerializer(value)
if isinstance(value, collections.Iterable): if isinstance(value, collections.Iterable):

View File

@ -2,6 +2,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime import datetime
import decimal
import functools import functools
import math import math
import os import os
@ -35,6 +36,15 @@ except ImportError:
enum = None enum = None
class Money(decimal.Decimal):
def deconstruct(self):
return (
'%s.%s' % (self.__class__.__module__, self.__class__.__name__),
[six.text_type(self)],
{}
)
class TestModel1(object): class TestModel1(object):
def upload_to(self): def upload_to(self):
return "somewhere dynamic" return "somewhere dynamic"
@ -200,6 +210,18 @@ class WriterTests(SimpleTestCase):
self.assertTrue(math.isinf(self.serialize_round_trip(float("-inf")))) self.assertTrue(math.isinf(self.serialize_round_trip(float("-inf"))))
self.assertTrue(math.isnan(self.serialize_round_trip(float("nan")))) self.assertTrue(math.isnan(self.serialize_round_trip(float("nan"))))
self.assertSerializedEqual(decimal.Decimal('1.3'))
self.assertSerializedResultEqual(
decimal.Decimal('1.3'),
("Decimal('1.3')", {'from decimal import Decimal'})
)
self.assertSerializedEqual(Money('1.3'))
self.assertSerializedResultEqual(
Money('1.3'),
("migrations.test_writer.Money('1.3')", {'import migrations.test_writer'})
)
def test_serialize_constants(self): def test_serialize_constants(self):
self.assertSerializedEqual(None) self.assertSerializedEqual(None)
self.assertSerializedEqual(True) self.assertSerializedEqual(True)