Skip to content

Commit 62770f4

Browse files
authored
Fix type checking of dict type aliases (#20170)
Resolves a bad false negative and a false positive Previously, for `D = dict[str, str]` we would require a type annotation for `d = D()` and we would fail to error on `D(x=1)` Fixes #11093, fixes #11246, fixes #13320, fixes #16047
1 parent 40821bf commit 62770f4

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

mypy/semanal.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5888,7 +5888,11 @@ def visit_call_expr(self, expr: CallExpr) -> None:
58885888
expr.analyzed = PromoteExpr(target)
58895889
expr.analyzed.line = expr.line
58905890
expr.analyzed.accept(self)
5891-
elif refers_to_fullname(expr.callee, "builtins.dict"):
5891+
elif refers_to_fullname(expr.callee, "builtins.dict") and not (
5892+
isinstance(expr.callee, RefExpr)
5893+
and isinstance(expr.callee.node, TypeAlias)
5894+
and not expr.callee.node.no_args
5895+
):
58925896
expr.analyzed = self.translate_dict_call(expr)
58935897
elif refers_to_fullname(expr.callee, "builtins.divmod"):
58945898
if not self.check_fixed_args(expr, 2, "divmod"):

test-data/unit/check-type-aliases.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,3 +1318,17 @@ from typing_extensions import TypeAlias
13181318

13191319
Foo: TypeAlias = ClassVar[int] # E: ClassVar[...] can't be used inside a type alias
13201320
[builtins fixtures/tuple.pyi]
1321+
1322+
1323+
[case testTypeAliasDict]
1324+
D = dict[str, int]
1325+
d = D()
1326+
reveal_type(d) # N: Revealed type is "builtins.dict[builtins.str, builtins.int]"
1327+
reveal_type(D()) # N: Revealed type is "builtins.dict[builtins.str, builtins.int]"
1328+
reveal_type(D(x=1)) # N: Revealed type is "builtins.dict[builtins.str, builtins.int]"
1329+
reveal_type(D(x="asdf")) # E: No overload variant of "dict" matches argument type "str" \
1330+
# N: Possible overload variants: \
1331+
# N: def __init__(self, **kwargs: int) -> dict[str, int] \
1332+
# N: def __init__(self, arg: Iterable[tuple[str, int]], **kwargs: int) -> dict[str, int] \
1333+
# N: Revealed type is "Any"
1334+
[builtins fixtures/dict.pyi]

0 commit comments

Comments
 (0)