#36878: Migration's ModelState has varying type for unique_together and
index_together options causing autodetector crash
-------------------------------------+-------------------------------------
Reporter: Markus Holtermann | Owner: Markus
| Holtermann
Type: Bug | Status: assigned
Component: Migrations | Version: dev
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Markus Holtermann):
In order to understand where the incorrect setting or the values came
from, I applied the following changes to the `state.py`:
{{{#!diff
diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py
index 057651b1df..7220673142 100644
--- a/django/db/migrations/state.py
+++ b/django/db/migrations/state.py
@@ -734,6 +734,32 @@ class StateApps(Apps):
pass
+class OptionsDict(dict):
+ def __getitem__(self, key):
+ val = super().__getitem__(key)
+ if "together" in key:
+ print(f"__getitem__({key!r}) = {val!r}")
+ return val
+
+ def __setitem__(self, key, value):
+ if "together" in key:
+ import inspect, textwrap
+
+ print(f"__setitem__({key!r}, {value!r})")
+ if not isinstance(value, set | tuple):
+ calling_frame = inspect.stack(3)[1]
+ code =
textwrap.indent("".join(calling_frame.code_context), " ")
+ print(
+ f" {calling_frame.filename}:{calling_frame.lineno}
in {calling_frame.function}\n{code}"
+ )
+ return super().__setitem__(key, value)
+
+ def __delitem__(self, key):
+ if "together" in key:
+ print(f"__delitem__({key!r})")
+ return super().__delitem__(key)
+
+
class ModelState:
"""
Represent a Django Model. Don't use the actual Model class as it's
not
@@ -751,7 +777,7 @@ class ModelState:
self.app_label = app_label
self.name = name
self.fields = dict(fields)
- self.options = options or {}
+ self.options = OptionsDict(options or {})
self.options.setdefault("indexes", [])
self.options.setdefault("constraints", [])
self.bases = bases or (models.Model,)
@@ -783,6 +809,37 @@ class ModelState:
"%r doesn't have one." % index
)
+ def __getattr__(self, name):
+ val = super().__getattr__(name)
+ if (
+ name == "options"
+ and val
+ and ("unique_together" in value or "index_together" in value)
+ ):
+ print(f"__getattr__({name!r}) = {val!r}")
+ return val
+
+ def __setattr__(self, name, value):
+ if name == "options" and (
+ "unique_together" in value or "index_together" in value
+ ):
+ import inspect, textwrap
+
+ if (
+ "unique_together" in value
+ and not isinstance(value["unique_together"], set | tuple)
+ or "index_together" in value
+ and not isinstance(value["index_together"], set | tuple)
+ ):
+ print(f"__setattr__({name!r}, {value!r})")
+ for i in range(1, 4):
+ calling_frame = inspect.stack(3)[i]
+ code =
textwrap.indent("".join(calling_frame.code_context), " ")
+ print(
+ f"
{calling_frame.filename}:{calling_frame.lineno} in
{calling_frame.function}\n{code}"
+ )
+ return super().__setattr__(name, value)
+
@cached_property
def name_lower(self):
return self.name.lower()
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36878#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/django-updates/0107019beb752dd9-a0ff4a78-89c3-4bdf-829a-72f012900c23-000000%40eu-central-1.amazonses.com.