microsoft / pyright

Static Type Checker for Python
Other
13.12k stars 1.4k forks source link

False negative when missing cases matching on union of enums #8674

Closed robert-bn closed 1 month ago

robert-bn commented 1 month ago

Consider the following code:

from enum import Enum
from typing import assert_never

class Enum1(Enum):
    A = 1
    C = 2

class Enum2(Enum):
    B = 1
    C = 2

def f(
    x: Enum2 | Enum1
):
    match x:
        case Enum2.B | Enum1.A | Enum2.C:
            return

    assert_never(x)

This produces no error with pyright 1.1.374 cli.

I would expect to see an error, as by my reasoning x should be narrowed to Literal[Enum1.C] after the match, not Never.

Note that the error disappears when the name of the member of A and B isn't the same. For example, if the enum members are renamed to

class Enum1(Enum):
    A = 1
    C = 2

class Enum2(Enum):
    B = 1
    D = 2

then pyright produces the error

error: Argument of type "Literal[Enum1.C]" cannot be assigned to parameter "arg" of type "Never" in function "assert_never"
    Type "Literal[Enum1.C]" is incompatible with type "Never"

as expected.

erictraut commented 1 month ago

Thanks for the bug report. This will be addressed in the next release.

erictraut commented 1 month ago

This is included in pyright 1.1.375.