Commit cc2ca9c5 authored by Simon Charette's avatar Simon Charette
Browse files

Fixed #25807 -- Instructed the migration writer about lazy objects.

Thanks to Trac alias mrgaolei for the report, Baptiste for the confirmation
and Tim for the review.
parent 83151486
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject
from django.utils import datetime_safe, six
from django.utils._os import upath
from django.utils.encoding import force_text
from django.utils.functional import Promise
from django.utils.functional import LazyObject, Promise
from django.utils.inspect import get_func_args
from django.utils.module_loading import module_dir
from django.utils.timezone import now, utc
@@ -350,6 +350,10 @@ class MigrationWriter(object):
        # process.
        if isinstance(value, Promise):
            value = force_text(value)
        elif isinstance(value, LazyObject):
            # The unwrapped value is returned as the first item of the
            # arguments tuple.
            value = value.__reduce__()[1][0]

        # Sequences
        if isinstance(value, (frozenset, list, set, tuple)):
+2 −1
Original line number Diff line number Diff line
@@ -451,7 +451,8 @@ Migrations
  :djadminopt:`migrate --fake-initial <--fake-initial>` to more easily detect
  initial migrations.

* Added support for serialization of ``functools.partial`` objects.
* Added support for serialization of ``functools.partial`` and ``LazyObject``
  instances.

* When supplying ``None`` as a value in :setting:`MIGRATION_MODULES`, Django
  will consider the app an app without migrations.
+3 −1
Original line number Diff line number Diff line
@@ -648,6 +648,7 @@ Django can serialize the following:
- ``enum.Enum`` instances
- ``functools.partial`` 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)
- Any class reference (must be in module's top-level scope)
@@ -655,7 +656,8 @@ Django can serialize the following:

.. versionchanged:: 1.9

    Serialization support for `functools.partial` was added.
    Serialization support for ``functools.partial`` and ``LazyObject``
    instances was added.

.. versionchanged:: 1.10

+6 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ from django.test import SimpleTestCase, ignore_warnings, mock
from django.utils import datetime_safe, six
from django.utils._os import upath
from django.utils.deconstruct import deconstructible
from django.utils.functional import SimpleLazyObject
from django.utils.timezone import FixedOffset, get_default_timezone, utc
from django.utils.translation import ugettext_lazy as _

@@ -234,6 +235,11 @@ class WriterTests(SimpleTestCase):
            ("[list, tuple, dict, set, frozenset]", set())
        )

    def test_serialize_lazy_objects(self):
        pattern = re.compile(r'^foo$', re.UNICODE)
        lazy_pattern = SimpleLazyObject(lambda: pattern)
        self.assertEqual(self.serialize_round_trip(lazy_pattern), pattern)

    @unittest.skipUnless(enum, "enum34 is required on Python 2")
    def test_serialize_enums(self):
        class TextEnum(enum.Enum):