From 3c5d0f029c108df2dd9181925c5bb11247171f78 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 2 Jan 2020 12:05:44 -0800 Subject: [PATCH] Fix regression in container check logic This PR fixes the crash reported in https://github.com/python/mypy/issues/8230, by replacing the 'pass' with the 'continue', as suggested. However, it does *not* fix the underlying root cause -- for example, changing the lambda input type to `Optional[T]` bypasses the check and triggers the crash again: ``` from typing import Callable, Optional, TypeVar T = TypeVar('T') def foo(f: Callable[[Optional[T]], bool], it: T) -> None: ... foo(reveal_type(lambda x: x in [1, 2] and bool()), 3) ``` I'll update the issue with what I discovered while investigating this, but I don't really have a deep understanding of how our generics/function inference/deferred passes logic works, so didn't feel comfortable volunteering a fix. So, I settled just for fixing the regression. --- mypy/checker.py | 2 +- test-data/unit/check-optional.test | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index ae829d1157c1b..5046d9431b4fe 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -3915,7 +3915,7 @@ def find_isinstance_check_helper(self, node: Expression) -> Tuple[TypeMap, TypeM # We only try and narrow away 'None' for now if not is_optional(item_type): - pass + continue collection_item_type = get_proper_type(builtin_item_type(collection_type)) if collection_item_type is None or is_optional(collection_item_type): diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test index 9c40d550699eb..bdc820d57c89b 100644 --- a/test-data/unit/check-optional.test +++ b/test-data/unit/check-optional.test @@ -550,6 +550,17 @@ else: reveal_type(b) # N: Revealed type is 'Union[__main__.A, None]' [builtins fixtures/ops.pyi] +[case testInferInWithErasedTypes] +from typing import TypeVar, Callable, Optional + +T = TypeVar('T') +def foo(f: Callable[[T], bool], it: T) -> None: ... +def bar(f: Callable[[Optional[T]], bool], it: T) -> None: ... + +foo(lambda x: x in [1, 2] and bool(), 3) +bar(lambda x: x in [1, 2] and bool(), 3) +[builtins fixtures/list.pyi] + [case testWarnNoReturnWorksWithStrictOptional] # flags: --warn-no-return def f() -> None: