Skip to content

Commit 53d0c22

Browse files
Fix migrations.RunSQL stubs (typeddjango#1803)
* Add test from docs * Relax str constraint * Add a typealis and a test case
1 parent 65d6430 commit 53d0c22

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

django-stubs/db/migrations/operations/special.pyi

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ from typing import Any, Literal, Protocol
44
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
55
from django.db.migrations.state import StateApps
66
from django.utils.datastructures import _ListOrTuple
7+
from typing_extensions import TypeAlias
78

89
from .base import Operation
910

11+
_SqlOperations: TypeAlias = str | _ListOrTuple[str | tuple[str, dict[str, Any] | _ListOrTuple[Any] | None]]
12+
1013
class SeparateDatabaseAndState(Operation):
1114
database_operations: Sequence[Operation]
1215
state_operations: Sequence[Operation]
@@ -17,14 +20,14 @@ class SeparateDatabaseAndState(Operation):
1720

1821
class RunSQL(Operation):
1922
noop: Literal[""]
20-
sql: str | _ListOrTuple[str | tuple[str, dict[str, Any] | _ListOrTuple[str] | None]]
21-
reverse_sql: str | None | _ListOrTuple[str | tuple[str, dict[str, Any] | _ListOrTuple[str] | None]]
23+
sql: _SqlOperations
24+
reverse_sql: _SqlOperations | None
2225
state_operations: Sequence[Operation]
2326
hints: Mapping[str, Any]
2427
def __init__(
2528
self,
26-
sql: str | _ListOrTuple[str | tuple[str, dict[str, Any] | _ListOrTuple[str] | None]],
27-
reverse_sql: str | None | _ListOrTuple[str | tuple[str, dict[str, Any] | _ListOrTuple[str] | None]] = ...,
29+
sql: _SqlOperations,
30+
reverse_sql: _SqlOperations | None = ...,
2831
state_operations: Sequence[Operation] | None = ...,
2932
hints: Mapping[str, Any] | None = ...,
3033
elidable: bool = ...,

tests/typecheck/db/migrations/test_operations.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,16 @@
1616
1717
RunSQL(sql=["SOME SQLS", ("SOME SQLS %s, %s", ["PARAM", "ANOTHER PARAM"])], reverse_sql=["SOME SQLS", ("SOME SQLS %s, %s", ["PARAM", "ANOTHER PARAM"])])
1818
19-
RunSQL(sql=("SOME SQL", {})) # E: Argument "sql" to "RunSQL" has incompatible type "Tuple[str, Dict[<nothing>, <nothing>]]"; expected "Union[str, Union[List[Union[str, Tuple[str, Union[Dict[str, Any], Union[List[str], Tuple[str, ...], Tuple[()]], None]]]], Tuple[Union[str, Tuple[str, Union[Dict[str, Any], Union[List[str], Tuple[str, ...], Tuple[()]], None]]], ...], Tuple[()]]]" [arg-type]
20-
RunSQL(sql=["SOME SQLS", ("SOME SQLS %s, %s", [object(), "ANOTHER PARAM"])]) # E: List item 0 has incompatible type "object"; expected "str" [list-item]
19+
RunSQL("INSERT INTO musician (name) VALUES ('Reinhardt');")
20+
RunSQL([("INSERT INTO musician (name) VALUES ('Reinhardt');", None)])
21+
RunSQL([("INSERT INTO musician (name) VALUES (%s);", ["Reinhardt"])])
22+
23+
query = "UPDATE posts SET category = %s WHERE category = ANY(%s);"
24+
RunSQL([(query, ['new category', ['retired category', 'another retired category']])])
25+
26+
RunSQL(sql=["SOME SQLS", ("SOME SQLS %s, %s", [object(), "ANOTHER PARAM"])])
27+
28+
RunSQL(sql=("SOME SQL", {})) # E: Argument "sql" to "RunSQL" has incompatible type "Tuple[str, Dict[<nothing>, <nothing>]]"; expected "Union[str, Union[List[Union[str, Tuple[str, Union[Dict[str, Any], Union[List[Any], Tuple[Any, ...], Tuple[()]], None]]]], Tuple[Union[str, Tuple[str, Union[Dict[str, Any], Union[List[Any], Tuple[Any, ...], Tuple[()]], None]]], ...], Tuple[()]]]" [arg-type]
29+
RunSQL(sql=("SOME SQL", 1)) # E: Argument "sql" to "RunSQL" has incompatible type "Tuple[str, int]"; expected "Union[str, Union[List[Union[str, Tuple[str, Union[Dict[str, Any], Union[List[Any], Tuple[Any, ...], Tuple[()]], None]]]], Tuple[Union[str, Tuple[str, Union[Dict[str, Any], Union[List[Any], Tuple[Any, ...], Tuple[()]], None]]], ...], Tuple[()]]]" [arg-type]
30+
RunSQL(sql=("SOME SQL", None)) # E: Argument "sql" to "RunSQL" has incompatible type "Tuple[str, None]"; expected "Union[str, Union[List[Union[str, Tuple[str, Union[Dict[str, Any], Union[List[Any], Tuple[Any, ...], Tuple[()]], None]]]], Tuple[Union[str, Tuple[str, Union[Dict[str, Any], Union[List[Any], Tuple[Any, ...], Tuple[()]], None]]], ...], Tuple[()]]]" [arg-type]
31+
RunSQL(sql=("SOME SQLS %(VAL)s", {1: "FOO"})) # E: Argument "sql" to "RunSQL" has incompatible type "Tuple[str, Dict[int, str]]"; expected "Union[str, Union[List[Union[str, Tuple[str, Union[Dict[str, Any], Union[List[Any], Tuple[Any, ...], Tuple[()]], None]]]], Tuple[Union[str, Tuple[str, Union[Dict[str, Any], Union[List[Any], Tuple[Any, ...], Tuple[()]], None]]], ...], Tuple[()]]]" [arg-type]

0 commit comments

Comments
 (0)