summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2015-11-25 12:31:23 -0500
committerSimon Charette <charette.s@gmail.com>2015-11-26 11:21:35 -0500
commitb4a1d545db19bb427af4043ce2c689dad856514f (patch)
tree3e5a60813e6ac434f2673563f2cb141a0b44fa9b
parentf7e599ad25e52e8108a2bf6c17fb203b398ed986 (diff)
[1.9.x] 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. Backport of cc2ca9c550fbf8fca8684b373a3c8e3618eea08e from master
-rw-r--r--django/db/migrations/writer.py6
-rw-r--r--docs/releases/1.9.txt3
-rw-r--r--docs/topics/migrations.txt4
-rw-r--r--tests/migrations/test_writer.py6
4 files changed, 16 insertions, 3 deletions
diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py
index aa9f393e4b..f48ac9a7b8 100644
--- a/django/db/migrations/writer.py
+++ b/django/db/migrations/writer.py
@@ -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
@@ -344,6 +344,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)):
diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt
index b167500c76..bf6f45b450 100644
--- a/docs/releases/1.9.txt
+++ b/docs/releases/1.9.txt
@@ -448,7 +448,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.
diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt
index 57b6c3216a..24236ec9da 100644
--- a/docs/topics/migrations.txt
+++ b/docs/topics/migrations.txt
@@ -659,6 +659,7 @@ Django can serialize the following:
- ``decimal.Decimal`` 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)
@@ -666,7 +667,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.
Django can serialize the following on Python 3 only:
diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py
index 12df772df5..b3c41565e3 100644
--- a/tests/migrations/test_writer.py
+++ b/tests/migrations/test_writer.py
@@ -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 _
@@ -229,6 +230,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)
+
def test_serialize_functions(self):
with six.assertRaisesRegex(self, ValueError, 'Cannot serialize function: lambda'):
self.assertSerializedEqual(lambda x: 42)