summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2022-07-20 07:34:21 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-07-26 11:41:19 +0200
commita1e9e9abc592b8f44fa798c6e4e225b1a04f757c (patch)
tree7c0713759aa50f55b639433675015e385c434e04
parentc773d5794eb425c4836c726bdf6e1e742c94e9c0 (diff)
Refs #27236 -- Reverted "Refs #27236 -- Added generic mechanism to handle the deprecation of migration operations."
This reverts commit 41019e48bbf082c985e6ba3bad34d118b903bff1.
-rw-r--r--django/core/checks/__init__.py1
-rw-r--r--django/core/checks/migrations.py12
-rw-r--r--django/core/checks/registry.py1
-rw-r--r--django/db/migrations/migration.py6
-rw-r--r--django/db/migrations/operations/base.py5
-rw-r--r--docs/ref/checks.txt5
-rw-r--r--docs/releases/4.2.txt3
-rw-r--r--docs/topics/checks.txt20
-rw-r--r--docs/topics/migrations.txt50
-rw-r--r--tests/check_framework/test_migrations.py101
-rw-r--r--tests/db_functions/migrations/0001_setup_extensions.py17
-rw-r--r--tests/postgres_tests/migrations/0001_setup_extensions.py33
12 files changed, 24 insertions, 230 deletions
diff --git a/django/core/checks/__init__.py b/django/core/checks/__init__.py
index deea0d471a..998ab9dee2 100644
--- a/django/core/checks/__init__.py
+++ b/django/core/checks/__init__.py
@@ -19,7 +19,6 @@ import django.core.checks.caches # NOQA isort:skip
import django.core.checks.compatibility.django_4_0 # NOQA isort:skip
import django.core.checks.database # NOQA isort:skip
import django.core.checks.files # NOQA isort:skip
-import django.core.checks.migrations # NOQA isort:skip
import django.core.checks.model_checks # NOQA isort:skip
import django.core.checks.security.base # NOQA isort:skip
import django.core.checks.security.csrf # NOQA isort:skip
diff --git a/django/core/checks/migrations.py b/django/core/checks/migrations.py
deleted file mode 100644
index 92649a59a9..0000000000
--- a/django/core/checks/migrations.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from django.core.checks import Tags, register
-
-
-@register(Tags.migrations)
-def check_migration_operations(**kwargs):
- from django.db.migrations.loader import MigrationLoader
-
- errors = []
- loader = MigrationLoader(None, ignore_no_migrations=True)
- for migration in loader.disk_migrations.values():
- errors.extend(migration.check())
- return errors
diff --git a/django/core/checks/registry.py b/django/core/checks/registry.py
index 328209130a..f4bdea8691 100644
--- a/django/core/checks/registry.py
+++ b/django/core/checks/registry.py
@@ -15,7 +15,6 @@ class Tags:
compatibility = "compatibility"
database = "database"
files = "files"
- migrations = "migrations"
models = "models"
security = "security"
signals = "signals"
diff --git a/django/db/migrations/migration.py b/django/db/migrations/migration.py
index 7cc3e22361..ea9d02a94a 100644
--- a/django/db/migrations/migration.py
+++ b/django/db/migrations/migration.py
@@ -219,12 +219,6 @@ class Migration:
name = new_name
return name
- def check(self):
- errors = []
- for operation in self.operations:
- errors.extend(operation.check_deprecation_details())
- return errors
-
class SwappableTuple(tuple):
"""
diff --git a/django/db/migrations/operations/base.py b/django/db/migrations/operations/base.py
index 40128174c7..7d4dff2597 100644
--- a/django/db/migrations/operations/base.py
+++ b/django/db/migrations/operations/base.py
@@ -1,8 +1,7 @@
from django.db import router
-from django.utils.deprecation import DeprecationForHistoricalMigrationMixin
-class Operation(DeprecationForHistoricalMigrationMixin):
+class Operation:
"""
Base class for migration operations.
@@ -34,8 +33,6 @@ class Operation(DeprecationForHistoricalMigrationMixin):
serialization_expand_args = []
- check_type = "migrations"
-
def __new__(cls, *args, **kwargs):
# We capture the arguments to make returning them trivial
self = object.__new__(cls)
diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt
index 55e4ca64b2..92278db659 100644
--- a/docs/ref/checks.txt
+++ b/docs/ref/checks.txt
@@ -83,7 +83,6 @@ Django's system checks are organized using the following tags:
you specify configured database aliases using the ``--database`` option when
calling the :djadmin:`check` command.
* ``files``: Checks files related configuration.
-* ``migrations``: Checks of migration operations.
* ``models``: Checks of model, field, and manager definitions.
* ``security``: Checks security related configuration.
* ``signals``: Checks on signal declarations and handler registrations.
@@ -95,10 +94,6 @@ Django's system checks are organized using the following tags:
Some checks may be registered with multiple tags.
-.. versionchanged:: 4.2
-
- The ``migrations`` tag was added.
-
Core system checks
==================
diff --git a/docs/releases/4.2.txt b/docs/releases/4.2.txt
index 3b8ae5596c..24458cfc86 100644
--- a/docs/releases/4.2.txt
+++ b/docs/releases/4.2.txt
@@ -172,8 +172,7 @@ Management Commands
Migrations
~~~~~~~~~~
-* The new :ref:`generic mechanism <migrations-removing-operation>` allows
- handling the deprecation of migration operations.
+* ...
Models
~~~~~~
diff --git a/docs/topics/checks.txt b/docs/topics/checks.txt
index 0864d6db38..9586466285 100644
--- a/docs/topics/checks.txt
+++ b/docs/topics/checks.txt
@@ -128,18 +128,18 @@ The code below is equivalent to the code above::
.. _field-checking:
-Field, model, manager, migration, and database checks
------------------------------------------------------
+Field, model, manager, and database checks
+------------------------------------------
In some cases, you won't need to register your check function -- you can
piggyback on an existing registration.
-Fields, models, model managers, migrations, and database backends all implement
-a ``check()`` method that is already registered with the check framework. If
-you want to add extra checks, you can extend the implementation on the base
-class, perform any extra checks you need, and append any messages to those
-generated by the base class. It's recommended that you delegate each check to
-separate methods.
+Fields, models, model managers, and database backends all implement a
+``check()`` method that is already registered with the check framework. If you
+want to add extra checks, you can extend the implementation on the base class,
+perform any extra checks you need, and append any messages to those generated
+by the base class. It's recommended that you delegate each check to separate
+methods.
Consider an example where you are implementing a custom field named
``RangedIntegerField``. This field adds ``min`` and ``max`` arguments to the
@@ -194,10 +194,6 @@ the only difference is that the check is a classmethod, not an instance method::
# ... your own checks ...
return errors
-.. versionchanged:: 4.2
-
- Migration checks were added.
-
Writing tests
-------------
diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt
index 2350ac756c..cf3451a782 100644
--- a/docs/topics/migrations.txt
+++ b/docs/topics/migrations.txt
@@ -503,56 +503,6 @@ database migrations such as ``__init__()``, ``deconstruct()``, and
which reference the field exist. For example, after squashing migrations and
removing the old ones, you should be able to remove the field completely.
-.. _migrations-removing-operation:
-
-Considerations when removing migration operations
-=================================================
-
-.. versionadded:: 4.2
-
-Removing custom operations from your project or third-party app will cause a
-problem if they are referenced in old migrations.
-
-To help with this situation, Django provides some operation attributes to
-assist with operation deprecation using the :doc:`system checks framework
-</topics/checks>`.
-
-Add the ``system_check_deprecated_details`` attribute to your operation similar
-to the following::
-
- class MyCustomOperation(Operation):
- system_check_deprecated_details = {
- "msg": (
- "MyCustomOperation has been deprecated. Support for it "
- "(except in historical migrations) will be removed in "
- "Django 5.1."
- ),
- "hint": "Use DifferentOperation instead.", # optional
- "id": "migrations.W900", # pick a unique ID for your operation.
- }
-
-After a deprecation period of your choosing (two or three feature releases for
-operations in Django itself), change the ``system_check_deprecated_details``
-attribute to ``system_check_removed_details`` and update the dictionary similar
-to::
-
- class MyCustomOperation(Operation):
- system_check_removed_details = {
- "msg": (
- "MyCustomOperation has been removed except for support in "
- "historical migrations."
- ),
- "hint': "Use DifferentOperation instead.",
- "id": "migrations.E900", # pick a unique ID for your operation.
- }
-
-You should keep the operation's methods that are required for it to operate in
-database migrations such as ``__init__()``, ``state_forwards()``,
-``database_forwards()``, and ``database_backwards()``. Keep this stub operation
-for as long as any migrations which reference the operation exist. For example,
-after squashing migrations and removing the old ones, you should be able to
-remove the operation completely.
-
.. _data-migrations:
Data Migrations
diff --git a/tests/check_framework/test_migrations.py b/tests/check_framework/test_migrations.py
deleted file mode 100644
index 0b00690e77..0000000000
--- a/tests/check_framework/test_migrations.py
+++ /dev/null
@@ -1,101 +0,0 @@
-from django.core import checks
-from django.db import migrations
-from django.db.migrations.operations.base import Operation
-from django.test import TestCase
-
-
-class DeprecatedMigrationOperationTests(TestCase):
- def test_default_operation(self):
- class MyOperation(Operation):
- system_check_deprecated_details = {}
-
- my_operation = MyOperation()
-
- class Migration(migrations.Migration):
- operations = [my_operation]
-
- self.assertEqual(
- Migration("name", "app_label").check(),
- [
- checks.Warning(
- msg="MyOperation has been deprecated.",
- obj=my_operation,
- id="migrations.WXXX",
- )
- ],
- )
-
- def test_user_specified_details(self):
- class MyOperation(Operation):
- system_check_deprecated_details = {
- "msg": "This operation is deprecated and will be removed soon.",
- "hint": "Use something else.",
- "id": "migrations.W999",
- }
-
- my_operation = MyOperation()
-
- class Migration(migrations.Migration):
- operations = [my_operation]
-
- self.assertEqual(
- Migration("name", "app_label").check(),
- [
- checks.Warning(
- msg="This operation is deprecated and will be removed soon.",
- obj=my_operation,
- hint="Use something else.",
- id="migrations.W999",
- )
- ],
- )
-
-
-class RemovedMigrationOperationTests(TestCase):
- def test_default_operation(self):
- class MyOperation(Operation):
- system_check_removed_details = {}
-
- my_operation = MyOperation()
-
- class Migration(migrations.Migration):
- operations = [my_operation]
-
- self.assertEqual(
- Migration("name", "app_label").check(),
- [
- checks.Error(
- msg=(
- "MyOperation has been removed except for support in historical "
- "migrations."
- ),
- obj=my_operation,
- id="migrations.EXXX",
- )
- ],
- )
-
- def test_user_specified_details(self):
- class MyOperation(Operation):
- system_check_removed_details = {
- "msg": "Support for this operation is gone.",
- "hint": "Use something else.",
- "id": "migrations.E999",
- }
-
- my_operation = MyOperation()
-
- class Migration(migrations.Migration):
- operations = [my_operation]
-
- self.assertEqual(
- Migration("name", "app_label").check(),
- [
- checks.Error(
- msg="Support for this operation is gone.",
- obj=my_operation,
- hint="Use something else.",
- id="migrations.E999",
- )
- ],
- )
diff --git a/tests/db_functions/migrations/0001_setup_extensions.py b/tests/db_functions/migrations/0001_setup_extensions.py
index 5909a96eb8..0289055499 100644
--- a/tests/db_functions/migrations/0001_setup_extensions.py
+++ b/tests/db_functions/migrations/0001_setup_extensions.py
@@ -1,22 +1,11 @@
-from django.db import migrations
-from django.db.migrations.operations.base import Operation
-
-
-class DummyOperation(Operation):
- def state_forwards(self, app_label, state):
- pass
-
- def database_forwards(self, app_label, schema_editor, from_state, to_state):
- pass
-
- def database_backwards(self, app_label, schema_editor, from_state, to_state):
- pass
+from unittest import mock
+from django.db import migrations
try:
from django.contrib.postgres.operations import CryptoExtension
except ImportError:
- CryptoExtension = DummyOperation
+ CryptoExtension = mock.Mock()
class Migration(migrations.Migration):
diff --git a/tests/postgres_tests/migrations/0001_setup_extensions.py b/tests/postgres_tests/migrations/0001_setup_extensions.py
index 3edeff7b82..090abf9649 100644
--- a/tests/postgres_tests/migrations/0001_setup_extensions.py
+++ b/tests/postgres_tests/migrations/0001_setup_extensions.py
@@ -1,17 +1,6 @@
-from django.db import connection, migrations
-from django.db.migrations.operations.base import Operation
-
-
-class DummyOperation(Operation):
- def state_forwards(self, app_label, state):
- pass
-
- def database_forwards(self, app_label, schema_editor, from_state, to_state):
- pass
-
- def database_backwards(self, app_label, schema_editor, from_state, to_state):
- pass
+from unittest import mock
+from django.db import connection, migrations
try:
from django.contrib.postgres.operations import (
@@ -26,14 +15,14 @@ try:
UnaccentExtension,
)
except ImportError:
- BloomExtension = DummyOperation
- BtreeGinExtension = DummyOperation
- BtreeGistExtension = DummyOperation
- CITextExtension = DummyOperation
- CreateExtension = DummyOperation
- HStoreExtension = DummyOperation
- TrigramExtension = DummyOperation
- UnaccentExtension = DummyOperation
+ BloomExtension = mock.Mock()
+ BtreeGinExtension = mock.Mock()
+ BtreeGistExtension = mock.Mock()
+ CITextExtension = mock.Mock()
+ CreateExtension = mock.Mock()
+ HStoreExtension = mock.Mock()
+ TrigramExtension = mock.Mock()
+ UnaccentExtension = mock.Mock()
needs_crypto_extension = False
else:
needs_crypto_extension = (
@@ -52,7 +41,7 @@ class Migration(migrations.Migration):
# dash in its name.
CreateExtension("uuid-ossp"),
# CryptoExtension is required for RandomUUID() on PostgreSQL < 13.
- CryptoExtension() if needs_crypto_extension else DummyOperation(),
+ CryptoExtension() if needs_crypto_extension else mock.Mock(),
HStoreExtension(),
TrigramExtension(),
UnaccentExtension(),