Skip to content

Commit

Permalink
Fixed #26555 -- Gave deconstructible objects a higher priority during…
Browse files Browse the repository at this point in the history
… serialization
  • Loading branch information
MarkusH committed May 4, 2016
1 parent 3204bc8 commit 3b38308
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 11 deletions.
23 changes: 12 additions & 11 deletions django/db/migrations/serializer.py
Expand Up @@ -329,6 +329,18 @@ def serializer_factory(value):
# tuple.
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.
if isinstance(value, frozenset):
return FrozensetSerializer(value)
Expand Down Expand Up @@ -362,19 +374,8 @@ def serializer_factory(value):
return TextTypeSerializer(value)
if isinstance(value, decimal.Decimal):
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):
return FunctoolsPartialSerializer(value)
# Anything that knows how to deconstruct itself.
if hasattr(value, 'deconstruct'):
return DeconstructableSerializer(value)
if isinstance(value, (types.FunctionType, types.BuiltinFunctionType)):
return FunctionTypeSerializer(value)
if isinstance(value, collections.Iterable):
Expand Down
22 changes: 22 additions & 0 deletions tests/migrations/test_writer.py
Expand Up @@ -2,6 +2,7 @@
from __future__ import unicode_literals

import datetime
import decimal
import functools
import math
import os
Expand Down Expand Up @@ -35,6 +36,15 @@
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):
def upload_to(self):
return "somewhere dynamic"
Expand Down Expand Up @@ -200,6 +210,18 @@ def test_serialize_numbers(self):
self.assertTrue(math.isinf(self.serialize_round_trip(float("-inf"))))
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):
self.assertSerializedEqual(None)
self.assertSerializedEqual(True)
Expand Down

0 comments on commit 3b38308

Please sign in to comment.