Skip to content

Commit 132ac0d

Browse files
joey-laminartushar-deepsource
authored andcommitted
Fix __init__ in Dataclasses inheriting from Any (python#11966)
Dataclasses that inherit from Any (actually another type that we don't know) should assume an (almost) arbitrary constructor. Fixes python#11921
1 parent 4daa7fb commit 132ac0d

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

mypy/plugins/dataclasses.py

+23-5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
from typing_extensions import Final
55

66
from mypy.nodes import (
7-
ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_POS, MDEF, Argument, AssignmentStmt, CallExpr,
8-
Context, Expression, JsonDict, NameExpr, RefExpr,
9-
SymbolTableNode, TempNode, TypeInfo, Var, TypeVarExpr, PlaceholderNode
7+
ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_POS, ARG_STAR, ARG_STAR2, MDEF,
8+
Argument, AssignmentStmt, CallExpr, Context, Expression, JsonDict,
9+
NameExpr, RefExpr, SymbolTableNode, TempNode, TypeInfo, Var, TypeVarExpr,
10+
PlaceholderNode
1011
)
1112
from mypy.plugin import ClassDefContext, SemanticAnalyzerPluginInterface
1213
from mypy.plugins.common import (
@@ -141,11 +142,28 @@ def transform(self) -> None:
141142
if (decorator_arguments['init'] and
142143
('__init__' not in info.names or info.names['__init__'].plugin_generated) and
143144
attributes):
145+
146+
args = [attr.to_argument() for attr in attributes if attr.is_in_init
147+
and not self._is_kw_only_type(attr.type)]
148+
149+
if info.fallback_to_any:
150+
# Make positional args optional since we don't know their order.
151+
# This will at least allow us to typecheck them if they are called
152+
# as kwargs
153+
for arg in args:
154+
if arg.kind == ARG_POS:
155+
arg.kind = ARG_OPT
156+
157+
nameless_var = Var('')
158+
args = [Argument(nameless_var, AnyType(TypeOfAny.explicit), None, ARG_STAR),
159+
*args,
160+
Argument(nameless_var, AnyType(TypeOfAny.explicit), None, ARG_STAR2),
161+
]
162+
144163
add_method(
145164
ctx,
146165
'__init__',
147-
args=[attr.to_argument() for attr in attributes if attr.is_in_init
148-
and not self._is_kw_only_type(attr.type)],
166+
args=args,
149167
return_type=NoneType(),
150168
)
151169

test-data/unit/check-dataclasses.test

+14
Original file line numberDiff line numberDiff line change
@@ -1522,3 +1522,17 @@ PublishedMessagesVar = dict[int, 'PublishedMessages']
15221522
class PublishedMessages:
15231523
left: int
15241524
[builtins fixtures/dataclasses.pyi]
1525+
1526+
[case testDataclassesAnyInherit]
1527+
# flags: --python-version 3.7
1528+
from dataclasses import dataclass
1529+
from typing import Any
1530+
B: Any
1531+
@dataclass
1532+
class A(B):
1533+
a: int
1534+
1535+
A(a=1, b=2)
1536+
A(1)
1537+
A(a="foo") # E: Argument "a" to "A" has incompatible type "str"; expected "int"
1538+
[builtins fixtures/dataclasses.pyi]

0 commit comments

Comments
 (0)