From de4e9d612a7633b3a7d992ced5c15dbd47310296 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Fri, 21 Jun 2024 02:26:18 -0700 Subject: [PATCH] Fix isinstance checks with PEP 604 unions containing None (#17415) Fixes #17413 --- mypy/checker.py | 4 ++++ test-data/unit/check-union-or-syntax.test | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/mypy/checker.py b/mypy/checker.py index 3a7f231ebf1d..d2562d5dd722 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -7316,7 +7316,11 @@ def is_writable_attribute(self, node: Node) -> bool: def get_isinstance_type(self, expr: Expression) -> list[TypeRange] | None: if isinstance(expr, OpExpr) and expr.op == "|": left = self.get_isinstance_type(expr.left) + if left is None and is_literal_none(expr.left): + left = [TypeRange(NoneType(), is_upper_bound=False)] right = self.get_isinstance_type(expr.right) + if right is None and is_literal_none(expr.right): + right = [TypeRange(NoneType(), is_upper_bound=False)] if left is None or right is None: return None return left + right diff --git a/test-data/unit/check-union-or-syntax.test b/test-data/unit/check-union-or-syntax.test index a1b63077eef9..fcf679fff401 100644 --- a/test-data/unit/check-union-or-syntax.test +++ b/test-data/unit/check-union-or-syntax.test @@ -226,6 +226,17 @@ isinstance(5, str | list[str]) isinstance(5, ParameterizedAlias) [builtins fixtures/type.pyi] +[case testIsInstanceUnionNone] +# flags: --python-version 3.10 +def foo(value: str | bool | None): + assert not isinstance(value, str | None) + reveal_type(value) # N: Revealed type is "builtins.bool" + +def bar(value: object): + assert isinstance(value, str | None) + reveal_type(value) # N: Revealed type is "Union[builtins.str, None]" +[builtins fixtures/type.pyi] + # TODO: Get this test to pass [case testImplicit604TypeAliasWithCyclicImportNotInStub-xfail]