From cf59b82996db6bbe5c6535f338ba1fac22d67975 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Mon, 14 Nov 2022 08:43:11 +0000 Subject: [PATCH] Fix crash on partial type inference within a lambda (#14087) Fixes #9654 Seems to be quite straightforward. Erased types should never be stored on variables, it is just a temporary thing for nested generic calls. --- mypy/checker.py | 15 ++++++++++++--- test-data/unit/check-incremental.test | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 8b1c8d3464fb..c104a75e8cd5 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -178,6 +178,7 @@ AnyType, CallableType, DeletedType, + ErasedType, FunctionLike, Instance, LiteralType, @@ -7040,11 +7041,15 @@ def is_valid_inferred_type(typ: Type, is_lvalue_final: bool = False) -> bool: return is_lvalue_final elif isinstance(proper_type, UninhabitedType): return False - return not typ.accept(NothingSeeker()) + return not typ.accept(InvalidInferredTypes()) -class NothingSeeker(TypeQuery[bool]): - """Find any types resulting from failed (ambiguous) type inference.""" +class InvalidInferredTypes(TypeQuery[bool]): + """Find type components that are not valid for an inferred type. + + These include type, and any types resulting from failed + (ambiguous) type inference. + """ def __init__(self) -> None: super().__init__(any) @@ -7052,6 +7057,10 @@ def __init__(self) -> None: def visit_uninhabited_type(self, t: UninhabitedType) -> bool: return t.ambiguous + def visit_erased_type(self, t: ErasedType) -> bool: + # This can happen inside a lambda. + return True + class SetNothingToAny(TypeTranslator): """Replace all ambiguous types with Any (to avoid spurious extra errors).""" diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 3ec0ed2c63f5..131cd039a467 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -6286,3 +6286,29 @@ class C: ... [out] [out2] [out3] + +[case testNoCrashOnPartialLambdaInference] +import m +[file m.py] +from typing import TypeVar, Callable + +V = TypeVar("V") +def apply(val: V, func: Callable[[V], None]) -> None: + return func(val) + +xs = [] +apply(0, lambda a: xs.append(a)) +[file m.py.2] +from typing import TypeVar, Callable + +V = TypeVar("V") +def apply(val: V, func: Callable[[V], None]) -> None: + return func(val) + +xs = [] +apply(0, lambda a: xs.append(a)) +reveal_type(xs) +[builtins fixtures/list.pyi] +[out] +[out2] +tmp/m.py:9: note: Revealed type is "builtins.list[builtins.int]"