summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sanders <shang.xiao.sanders@gmail.com>2024-02-08 19:57:14 +1100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2024-02-09 09:37:13 +0100
commit06264258dc7c7cc69b2ba5f70f782988ccb2b06c (patch)
treec9d7de1b02e85888bbaf194a673567a1eabc15c1
parent8b7ddd1b621e1396cf87c08faf11937732f09dcd (diff)
Fixed #35175 -- Made migraton writer preserve keyword-only arguments.
Thanks Gerald Goh for the report.
-rw-r--r--django/utils/inspect.py15
-rw-r--r--tests/custom_migration_operations/operations.py5
-rw-r--r--tests/migrations/test_writer.py18
-rw-r--r--tests/postgres_tests/test_operations.py20
4 files changed, 53 insertions, 5 deletions
diff --git a/django/utils/inspect.py b/django/utils/inspect.py
index 28418f7312..81a15ed2db 100644
--- a/django/utils/inspect.py
+++ b/django/utils/inspect.py
@@ -16,13 +16,18 @@ def _get_callable_parameters(meth_or_func):
return _get_func_parameters(func, remove_first=is_method)
+ARG_KINDS = frozenset(
+ {
+ inspect.Parameter.POSITIONAL_ONLY,
+ inspect.Parameter.KEYWORD_ONLY,
+ inspect.Parameter.POSITIONAL_OR_KEYWORD,
+ }
+)
+
+
def get_func_args(func):
params = _get_callable_parameters(func)
- return [
- param.name
- for param in params
- if param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD
- ]
+ return [param.name for param in params if param.kind in ARG_KINDS]
def get_func_full_args(func):
diff --git a/tests/custom_migration_operations/operations.py b/tests/custom_migration_operations/operations.py
index f63f0b2a3a..6bed8559d1 100644
--- a/tests/custom_migration_operations/operations.py
+++ b/tests/custom_migration_operations/operations.py
@@ -68,6 +68,11 @@ class ArgsKwargsOperation(TestOperation):
)
+class ArgsAndKeywordOnlyArgsOperation(ArgsKwargsOperation):
+ def __init__(self, arg1, arg2, *, kwarg1, kwarg2):
+ super().__init__(arg1, arg2, kwarg1=kwarg1, kwarg2=kwarg2)
+
+
class ExpandArgsOperation(TestOperation):
serialization_expand_args = ["arg"]
diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py
index a2ac673804..891efd8ac7 100644
--- a/tests/migrations/test_writer.py
+++ b/tests/migrations/test_writer.py
@@ -152,6 +152,24 @@ class OperationWriterTests(SimpleTestCase):
"),",
)
+ def test_keyword_only_args_signature(self):
+ operation = (
+ custom_migration_operations.operations.ArgsAndKeywordOnlyArgsOperation(
+ 1, 2, kwarg1=3, kwarg2=4
+ )
+ )
+ buff, imports = OperationWriter(operation, indentation=0).serialize()
+ self.assertEqual(imports, {"import custom_migration_operations.operations"})
+ self.assertEqual(
+ buff,
+ "custom_migration_operations.operations.ArgsAndKeywordOnlyArgsOperation(\n"
+ " arg1=1,\n"
+ " arg2=2,\n"
+ " kwarg1=3,\n"
+ " kwarg2=4,\n"
+ "),",
+ )
+
def test_nested_args_signature(self):
operation = custom_migration_operations.operations.ArgsOperation(
custom_migration_operations.operations.ArgsOperation(1, 2),
diff --git a/tests/postgres_tests/test_operations.py b/tests/postgres_tests/test_operations.py
index ff344e3cb0..bc2ae42096 100644
--- a/tests/postgres_tests/test_operations.py
+++ b/tests/postgres_tests/test_operations.py
@@ -4,6 +4,7 @@ from migrations.test_base import OperationTestBase
from django.db import IntegrityError, NotSupportedError, connection, transaction
from django.db.migrations.state import ProjectState
+from django.db.migrations.writer import OperationWriter
from django.db.models import CheckConstraint, Index, Q, UniqueConstraint
from django.db.utils import ProgrammingError
from django.test import modify_settings, override_settings
@@ -393,6 +394,25 @@ class CreateCollationTests(PostgreSQLTestCase):
self.assertEqual(len(captured_queries), 1)
self.assertIn("DROP COLLATION", captured_queries[0]["sql"])
+ def test_writer(self):
+ operation = CreateCollation(
+ "sample_collation",
+ "und-u-ks-level2",
+ provider="icu",
+ deterministic=False,
+ )
+ buff, imports = OperationWriter(operation, indentation=0).serialize()
+ self.assertEqual(imports, {"import django.contrib.postgres.operations"})
+ self.assertEqual(
+ buff,
+ "django.contrib.postgres.operations.CreateCollation(\n"
+ " name='sample_collation',\n"
+ " locale='und-u-ks-level2',\n"
+ " provider='icu',\n"
+ " deterministic=False,\n"
+ "),",
+ )
+
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific tests.")
class RemoveCollationTests(PostgreSQLTestCase):