microsoft / microsoft/pyright

Valid match cases are reported as unreachable

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

Description

**Describe the bug**
A clear and concise description of the behavior you are seeing and the expected behavior along with steps to reproduce it.

Matching a class instance using string cases (or I guess other literals) causes pyright to report that a case block is unreachable, even if at runtime it works correctly, the object overrides `__eq__`.
Also from my understanding the specification allows such a case, by stating

>In simple terms, LITERAL will succeed only if \ == LITERAL. For the singletons None, True and False, the [is](https://docs.python.org/3/reference/expressions.html#is) operator is used.

https://docs.python.org/3/reference/compound_stmts.html#literal-patterns

**Code or Screenshots**

```python
class X:
__match_args__ = ("a",)

def __init__(self, x, y, a):
self.a = a

def __eq__(self, value: object) -> bool:
return self.a == value.a if isinstance(value, X) else self.a == value

def go_match_str(a: X) -> int | str:
match a:
case "a":
return 1
case "b":
return 2
case _:
return "nope"

def go_match_X(a: X) -> int | str:
match a:
case X("a"):
return 1
case X("b"):
return 2
case _:
return "nope"

def go_if(a: X) -> int | str:
if a == "a":
return 1
elif a == "b":
return 2
else:
return "nope"

xs = [X(1, 1, "a"), X(2, 2, "b"), X(0, 0, "c")]
assert [go_match_str(x) for x in xs] == [1, 2, "nope"]
assert [go_match_X(x) for x in xs] == [1, 2, "nope"]
assert [go_if(x) for x in xs] == [1, 2, "nope"]
```

the code above triggers no assertion errors but accorting to pyright go_match_str will only match the wildcard pattern:

Image

**VS Code extension or command-line**
Are you running pyright as a VS Code extension, a language server in another editor, integrated into Pylance, or the command-line tool? Which version?

the above image is via pylance, but enabling `reportUnreachable = true` pytight on the above code also reports errors:
>13:13 - error: Type analysis indicates code is unreachable
>15:13 - error: Type analysis indicates code is unreachable

version is pyright 1.1.407

Contributor guide

Open the contributing guide

Research direction

Start with the provided go_match_str, go_match_X, and go_if examples and inspect Pyright's pattern-matching and unreachable-code analysis. Compare literal-pattern handling with the runtime assertions and confirm that enabling reportUnreachable no longer marks the valid string cases as unreachable.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.