Skip to content

Commit 071f0f3

Browse files
committed
Fix crash on unimported Any with Required/NotRequired
Fixes #17604; fixes #17608. (To reproduce the crash without mypyc, replace `cast(ProperType, typ)` with an assertion in `get_proper_type`.) Signed-off-by: Anders Kaseorg <[email protected]>
1 parent 8b74b5a commit 071f0f3

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

mypy/checker.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
Overloaded,
199199
PartialType,
200200
ProperType,
201+
RequiredType,
201202
TupleType,
202203
Type,
203204
TypeAliasType,
@@ -2945,7 +2946,11 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None:
29452946
"A type on this line", AnyType(TypeOfAny.special_form), s
29462947
)
29472948
else:
2948-
self.msg.unimported_type_becomes_any("Type of variable", s.type, s)
2949+
self.msg.unimported_type_becomes_any(
2950+
"Type of variable",
2951+
s.type.item if isinstance(s.type, RequiredType) else s.type,
2952+
s,
2953+
)
29492954
check_for_explicit_any(s.type, self.options, self.is_typeshed_stub, self.msg, context=s)
29502955

29512956
if len(s.lvalues) > 1:

mypy/stats.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
CallableType,
4949
FunctionLike,
5050
Instance,
51+
RequiredType,
5152
TupleType,
5253
Type,
5354
TypeOfAny,
@@ -205,7 +206,7 @@ def visit_assignment_stmt(self, o: AssignmentStmt) -> None:
205206
if o.type:
206207
# If there is an explicit type, don't visit the l.h.s. as an expression
207208
# to avoid double-counting and mishandling special forms.
208-
self.type(o.type)
209+
self.type(o.type.item if isinstance(o.type, RequiredType) else o.type)
209210
o.rvalue.accept(self)
210211
return
211212
elif self.inferred and not self.all_nodes:

test-data/unit/check-typeddict.test

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,6 +2394,14 @@ class ForceDeferredEval: pass
23942394
[builtins fixtures/dict.pyi]
23952395
[typing fixtures/typing-typeddict.pyi]
23962396

2397+
[case testTypedDictRequiredUnimportedAny]
2398+
# flags: --disallow-any-unimported
2399+
from typing import NotRequired, TypedDict
2400+
from nonexistent import Foo # type: ignore[import-not-found]
2401+
class Bar(TypedDict):
2402+
foo: NotRequired[Foo] # E: Type of variable becomes "Any" due to an unfollowed import
2403+
[typing fixtures/typing-typeddict.pyi]
2404+
23972405
-- Required[]
23982406

23992407
[case testDoesRecognizeRequiredInTypedDictWithClass]

0 commit comments

Comments
 (0)