From 75aa4cc6229910b519040e2716b1e1da5ca620cf Mon Sep 17 00:00:00 2001
From: "Yury V. Zaytsev" <yury.zaytsev@moneymeets.com>
Date: Thu, 6 Jul 2023 18:09:21 +0200
Subject: [PATCH] Fixed #34697 -- Added serializer for unordered sequences to
ensure stable migration writer output.
---
AUTHORS | 1 +
django/db/migrations/serializer.py | 9 +++++++--
tests/migrations/test_writer.py | 2 ++
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index 40df3589c0..00a79b330c 100644
a
|
b
|
answer newbie questions, and generally made Django that much better:
|
1042 | 1042 | ye7cakf02@sneakemail.com |
1043 | 1043 | ymasuda@ethercube.com |
1044 | 1044 | Yoong Kang Lim <yoongkang.lim@gmail.com> |
| 1045 | Yury V. Zaytsev <yury@shurup.com> |
1045 | 1046 | Yusuke Miyazaki <miyazaki.dev@gmail.com> |
1046 | 1047 | yyyyyyyan <contact@yyyyyyyan.tech> |
1047 | 1048 | Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com> |
diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py
index 454feaa829..d88cda6e20 100644
a
|
b
|
class BaseSequenceSerializer(BaseSerializer):
|
46 | 46 | return value % (", ".join(strings)), imports |
47 | 47 | |
48 | 48 | |
| 49 | class BaseUnorderedSequenceSerializer(BaseSequenceSerializer): |
| 50 | def __init__(self, value): |
| 51 | super().__init__(sorted(value, key=repr)) |
| 52 | |
| 53 | |
49 | 54 | class BaseSimpleSerializer(BaseSerializer): |
50 | 55 | def serialize(self): |
51 | 56 | return repr(self.value), set() |
… |
… |
class FloatSerializer(BaseSimpleSerializer):
|
151 | 156 | return super().serialize() |
152 | 157 | |
153 | 158 | |
154 | | class FrozensetSerializer(BaseSequenceSerializer): |
| 159 | class FrozensetSerializer(BaseUnorderedSequenceSerializer): |
155 | 160 | def _format(self): |
156 | 161 | return "frozenset([%s])" |
157 | 162 | |
… |
… |
class SequenceSerializer(BaseSequenceSerializer):
|
279 | 284 | return "[%s]" |
280 | 285 | |
281 | 286 | |
282 | | class SetSerializer(BaseSequenceSerializer): |
| 287 | class SetSerializer(BaseUnorderedSequenceSerializer): |
283 | 288 | def _format(self): |
284 | 289 | # Serialize as a set literal except when value is empty because {} |
285 | 290 | # is an empty dict. |
diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py
index 33b52bd538..4cef9a7bbd 100644
a
|
b
|
class WriterTests(SimpleTestCase):
|
774 | 774 | self.assertSerializedResultEqual(set(), ("set()", set())) |
775 | 775 | self.assertSerializedEqual({"a"}) |
776 | 776 | self.assertSerializedResultEqual({"a"}, ("{'a'}", set())) |
| 777 | self.assertSerializedEqual({"c", "b", "a"}) |
| 778 | self.assertSerializedResultEqual({"c", "b", "a"}, ("{'a', 'b', 'c'}", set())) |
777 | 779 | |
778 | 780 | def test_serialize_timedelta(self): |
779 | 781 | self.assertSerializedEqual(datetime.timedelta()) |