microsoft / pyright

Static Type Checker for Python
Other
13.04k stars 1.39k forks source link

Type narrowing with assert and isinstance() doesn't work correctly for Union types #8358

Closed minmax closed 1 month ago

minmax commented 1 month ago

pyright 1.1.371

from typing import TypeAlias
from typing import reveal_type

class A:
    pass

class B:
    pass

class C:
    pass

AB: TypeAlias = A | B
ABC: TypeAlias = AB | C

class Foo:
    def get_ab(self) -> AB:
        v = self.get_abc()
        reveal_type(v)  # Type of "v" is "A | B | C"

        assert isinstance(v, AB), v

        reveal_type(v)  # Type of "v" is "A | B | C"
        return v

    def get_abc(self) -> ABC: ...

I found that assert without second part work as expected, but if i pass context to assert, type not narrowed correctly.

assert isinstance(v, AB) - good assert isinstance(v, AB), v - bad

related issue: https://github.com/microsoft/pyright/issues/8302

erictraut commented 1 month ago

This is addressed in pyright 1.1.372.