microsoft / microsoft/pyright

Use match case guard to narrow else cases

Open
#10,852 0 comments 0 reactions 0 assignees View on GitHub
enhancement request
Dominant language
Python
Stars
15.6k
Forks
1.8k
Avg merge
12h 13m
Merged PRs (30d)
52

Description

**Is your feature request related to a problem? Please describe.**
```python
def f(var: str | bool | None) -> None:
match var:
case _ if not var:
reveal_type(var)
case _:
reveal_type(var) # can be narrowed to: str | Literal[True]
```

The case guard `if not var` can be used to narrow `var` for the else case.
This works in mypy `v1.17.1` and it would be great if pyright could support it as well.

The logic seems to be partially implemented already. E.g. with just patterns the else case is narrowed correctly.
```py
def f(var: str | bool | None) -> None:
match var:
case None:
reveal_type(var)
case _:
reveal_type(var) # str | bool
```

--
pyright 1.1.404

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the reported examples with pyright 1.1.404, comparing the guarded match case with the pattern-only case. Trace the existing match-case narrowing behavior and make the else branch account for the `if not var` guard; done when the second `reveal_type(var)` reports `str | Literal[True]`.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.