DetachHead / basedpyright

pyright fork with various type checking improvements, improved vscode support and pylance features built into the language server
https://docs.basedpyright.com
Other
1.11k stars 20 forks source link

equality checks should narrow tuple types #347

Open AlexBlandin opened 5 months ago

AlexBlandin commented 5 months ago

Version: BasedPyright v1.12.0

Cases within match statement do not exhaustively handle all values
  Unhandled type: "tuple[bool, bool]"
  If exhaustive handling is not intended, add "case _: pass"

basedpyright(reportMatchNotExhaustive)

As seen below, the snippet foo has this error on a, b, while bar passes.


def foo(a: bool, b: bool) -> None:
  match a, b:
    case (True, True):
      pass
    case (True, False):
      pass
    case (False, True):
      pass
    case (False, False):
      pass

def bar(a: bool) -> None:
  match (a,):
    case (True,):
      pass
    case (False,):
      pass
DetachHead commented 5 months ago

it's not just match statements. the issue is that equality checks on tuples don't narrow their type:

from typing import assert_never

def bar(a: tuple[bool]) -> None:
    if a == (True,):
        ...
    elif a == (False,):
        ...
    else:
        assert_never(a) # error: Type "tuple[bool]" is incompatible with type "Never"

looks like this has been raised upstream but was rejected: https://github.com/microsoft/pyright/issues/6437

DetachHead commented 3 months ago

looks like it was fixed upstream for match statements but not if statements