Skip to content

Commit 88ae1e4

Browse files
authored
Fix crash on star unpack in TypedDict (#16116)
Fixes #16107 Fixes #15891 I only vaguely remember why I added those context managers, it seemed to me giving full TypedDict as context may cause false positives. But since the current way causes crashes, let's just not do this (we will see if there will be actual false positives).
1 parent 2bbc42f commit 88ae1e4

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

mypy/checkexpr.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -813,8 +813,7 @@ def validate_star_typeddict_item(
813813
Note `result` and `always_present_keys` are updated in place. Return true if the
814814
expression `item_arg` may valid in `callee` TypedDict context.
815815
"""
816-
with self.chk.local_type_map(), self.msg.filter_errors():
817-
inferred = get_proper_type(self.accept(item_arg, type_context=callee))
816+
inferred = get_proper_type(self.accept(item_arg, type_context=callee))
818817
possible_tds = []
819818
if isinstance(inferred, TypedDictType):
820819
possible_tds = [inferred]

test-data/unit/check-typeddict.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3224,3 +3224,15 @@ t2: Foo = {**y} # E: Missing key "a" for TypedDict "Foo"
32243224
t3: Foo = {**z} # E: Missing key "a" for TypedDict "Foo"
32253225
[builtins fixtures/dict.pyi]
32263226
[typing fixtures/typing-typeddict.pyi]
3227+
3228+
[case testTypedDictUnpackError]
3229+
from typing import TypedDict
3230+
3231+
class Foo(TypedDict):
3232+
a: int
3233+
3234+
def foo(x: int) -> Foo: ...
3235+
3236+
f: Foo = {**foo("no")} # E: Argument 1 to "foo" has incompatible type "str"; expected "int"
3237+
[builtins fixtures/dict.pyi]
3238+
[typing fixtures/typing-typeddict.pyi]

test-data/unit/reports.test

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,40 @@ def untyped_function():
6969
</packages>
7070
</coverage>
7171

72+
[case testCoberturaStarUnpacking]
73+
# cmd: mypy --cobertura-xml-report build a.py
74+
[file a.py]
75+
from typing import TypedDict
76+
77+
class MyDict(TypedDict):
78+
a: int
79+
80+
def foo(a: int) -> MyDict:
81+
return {"a": a}
82+
md: MyDict = MyDict(**foo(42))
83+
[outfile build/cobertura.xml]
84+
<coverage timestamp="$TIMESTAMP" version="$VERSION" line-rate="0.8333" branch-rate="0">
85+
<sources>
86+
<source>$PWD</source>
87+
</sources>
88+
<packages>
89+
<package complexity="1.0" name="a" branch-rate="0" line-rate="0.8333">
90+
<classes>
91+
<class complexity="1.0" filename="a.py" name="a.py" branch-rate="0" line-rate="0.8333">
92+
<methods/>
93+
<lines>
94+
<line branch="false" hits="1" number="1" precision="precise"/>
95+
<line branch="false" hits="1" number="3" precision="precise"/>
96+
<line branch="false" hits="0" number="4" precision="any"/>
97+
<line branch="false" hits="1" number="6" precision="precise"/>
98+
<line branch="false" hits="1" number="7" precision="precise"/>
99+
<line branch="false" hits="1" number="8" precision="precise"/>
100+
</lines>
101+
</class>
102+
</classes>
103+
</package>
104+
</packages>
105+
</coverage>
72106

73107
[case testAnyExprReportDivisionByZero]
74108
# cmd: mypy --any-exprs-report=out -c 'pass'

0 commit comments

Comments
 (0)