KEMBAR78
Union of generics not fully narrowed with isinstance · Issue #10287 · python/mypy · GitHub
Skip to content

Union of generics not fully narrowed with isinstance #10287

@ariebovenberg

Description

@ariebovenberg

Bug Report

It appears that isinstance checks don't narrow down the type of a union of generics completely.

I found some related issues, but none that appeared to match my case exactly. Issue #7600 may be the closest.

To Reproduce

# mypy: warn_unreachable
from typing import Generic, TypeVar, Union

T = TypeVar("T")
class A(Generic[T]): pass
class B(Generic[T]): pass
AorB = Union[A[T], B[T]]

x: AorB

if isinstance(x, A):
    print("A")
elif isinstance(x, B):
    print("B")
else:
    # correctly identified as unreachable
    reveal_type(x)
    print("not possible!")

y: AorB[int]

if isinstance(y, A):
    print("A")
elif isinstance(y, B):
    print("B")
else:
    # NOT identified as unreachable, although it should be
    reveal_type(y)
    print("not possible!")

Expected Behavior

Expect to have 2 "Statement is unreachable" errors.

Actual Behavior

  • The version without type parameter (x: AorB) works ✅
  • The version with type parameter (y: AorB[int]) doesn't work ❌
$ mypy bug.py
bug.py:25: error: Statement is unreachable
bug.py:38: note: Revealed type is 'bug.B[builtins.int]'
Found 1 error in 1 file (checked 1 source file)

Interestingly, if we do isinstance(y, B[int]) the statement is marked correctly as unreachable. (Of course, isinstance is not usable like that.)

Your Environment

  • Mypy version used: 0.812
  • Mypy command-line flags: none (warn_unreachable set in file)
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.9.1
  • Operating system and version: MacOS 11.2.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions