From 54a30a7a00fea6c5e3702282ade6e0238e06de3b Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Tue, 10 Aug 2021 09:58:40 +0200 Subject: [PATCH] Refs #29898 -- Changed ProjectState.real_apps to set. --- django/db/migrations/executor.py | 2 +- django/db/migrations/loader.py | 2 +- django/db/migrations/state.py | 12 +++++++----- tests/auth_tests/test_management.py | 2 +- tests/migrations/test_autodetector.py | 4 ++-- tests/migrations/test_state.py | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/django/db/migrations/executor.py b/django/db/migrations/executor.py index a8a189f7d9..db9013575e 100644 --- a/django/db/migrations/executor.py +++ b/django/db/migrations/executor.py @@ -66,7 +66,7 @@ class MigrationExecutor: Create a project state including all the applications without migrations and applied migrations if with_applied_migrations=True. """ - state = ProjectState(real_apps=list(self.loader.unmigrated_apps)) + state = ProjectState(real_apps=self.loader.unmigrated_apps) if with_applied_migrations: # Create the forwards plan Django would follow on an empty database full_plan = self.migration_plan(self.loader.graph.leaf_nodes(), clean_start=True) diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index c0837140af..93fb2c3bd5 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -335,7 +335,7 @@ class MigrationLoader: See graph.make_state() for the meaning of "nodes" and "at_end". """ - return self.graph.make_state(nodes=nodes, at_end=at_end, real_apps=list(self.unmigrated_apps)) + return self.graph.make_state(nodes=nodes, at_end=at_end, real_apps=self.unmigrated_apps) def collect_sql(self, plan): """ diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index af9093c4e8..088f5c41f0 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -91,7 +91,10 @@ class ProjectState: def __init__(self, models=None, real_apps=None): self.models = models or {} # Apps to include from main registry, usually unmigrated ones - self.real_apps = real_apps or [] + if real_apps: + self.real_apps = real_apps if isinstance(real_apps, set) else set(real_apps) + else: + self.real_apps = set() self.is_delayed = False # {remote_model_key: {model_key: [(field_name, field)]}} self.relations = None @@ -352,7 +355,6 @@ class ProjectState: self.relations = defaultdict(partial(defaultdict, list)) concretes, proxies = self._get_concrete_models_mapping_and_proxy_models() - real_apps = set(self.real_apps) for model_key in concretes: model_state = self.models[model_key] for field_name, field in model_state.fields.items(): @@ -360,7 +362,7 @@ class ProjectState: if not remote_field: continue remote_model_key = resolve_relation(remote_field.model, *model_key) - if remote_model_key[0] not in real_apps and remote_model_key in concretes: + if remote_model_key[0] not in self.real_apps and remote_model_key in concretes: remote_model_key = concretes[remote_model_key] self.relations[remote_model_key][model_key].append((field_name, field)) @@ -368,7 +370,7 @@ class ProjectState: if not through: continue through_model_key = resolve_relation(through, *model_key) - if through_model_key[0] not in real_apps and through_model_key in concretes: + if through_model_key[0] not in self.real_apps and through_model_key in concretes: through_model_key = concretes[through_model_key] self.relations[through_model_key][model_key].append((field_name, field)) for model_key in proxies: @@ -432,7 +434,7 @@ class ProjectState: return cls(app_models) def __eq__(self, other): - return self.models == other.models and set(self.real_apps) == set(other.real_apps) + return self.models == other.models and self.real_apps == other.real_apps class AppConfigStub(AppConfig): diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 517c0697da..6180773211 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -1131,7 +1131,7 @@ class CreatePermissionsTests(TestCase): with self.assertNumQueries(0): create_permissions(self.app_config, verbosity=0, apps=state.apps) # Unavailable auth.Permission - state = migrations.state.ProjectState(real_apps=['contenttypes']) + state = migrations.state.ProjectState(real_apps={'contenttypes'}) with self.assertNumQueries(0): create_permissions(self.app_config, verbosity=0, apps=state.apps) diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index 5b12d3da58..dfb8bd67bb 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -2412,7 +2412,7 @@ class AutodetectorTests(TestCase): loader = MigrationLoader(connection) before = self.make_project_state([]) after = self.make_project_state([self.book_migrations_fk]) - after.real_apps = ["migrations"] + after.real_apps = {'migrations'} autodetector = MigrationAutodetector(before, after) changes = autodetector._detect_changes(graph=loader.graph) # Right number/type of migrations? @@ -2431,7 +2431,7 @@ class AutodetectorTests(TestCase): loader = MigrationLoader(connection) before = self.make_project_state([]) after = self.make_project_state([self.book_migrations_fk]) - after.real_apps = ["migrations"] + after.real_apps = {'migrations'} autodetector = MigrationAutodetector(before, after) changes = autodetector._detect_changes(graph=loader.graph) # Right number/type of migrations? diff --git a/tests/migrations/test_state.py b/tests/migrations/test_state.py index 2983e7e2cd..01ffc48802 100644 --- a/tests/migrations/test_state.py +++ b/tests/migrations/test_state.py @@ -916,7 +916,7 @@ class StateTests(SimpleTestCase): project_state.apps # If we include the real app it should succeed - project_state = ProjectState(real_apps=["contenttypes"]) + project_state = ProjectState(real_apps={'contenttypes'}) project_state.add_model(ModelState.from_model(TestModel)) rendered_state = project_state.apps self.assertEqual(