From a1136d93d89c54966bf60ec8c9ba0d2c2249d08d Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 2 Jan 2020 12:05:44 -0800 Subject: [PATCH 1/2] 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 -- I don't think I actually understand the relevant pieces of code enough to feel confident volunteering a fix. So, I settled for just fixing the regression. Basically, it seems this bug is due to how we try inferring the type of the lambda in multiple passes to resolve the types. We pencil in an ErasedType during the first pass -- and then subsequently crash when attempting to type check the body during that pass. I'll leave more details about this in the linked issue. --- 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 ae829d1157c1..5046d9431b4f 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 9c40d550699e..bdc820d57c89 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: From a7c2ee42419fb5aecc62d6f11b0b70426a497d23 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Thu, 2 Jan 2020 15:31:29 -0800 Subject: [PATCH 2/2] Remove second experimental test case --- test-data/unit/check-optional.test | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test-data/unit/check-optional.test b/test-data/unit/check-optional.test index bdc820d57c89..15698e99ddf5 100644 --- a/test-data/unit/check-optional.test +++ b/test-data/unit/check-optional.test @@ -551,14 +551,12 @@ else: [builtins fixtures/ops.pyi] [case testInferInWithErasedTypes] -from typing import TypeVar, Callable, Optional +from typing import TypeVar, Callable 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]