Wrong (missing?) type inference on `{}` in match/case
- Dominant language
- Python
- Stars
- 15.6k
- Forks
- 1.8k
- Avg merge
- 12h 13m
- Merged PRs (30d)
- 52
Description
**Describe the bug**
A `case {}:` as a match branch does not cause the matched value to be inferred to be a dict.
**Code or Screenshots**
```python
from typing import reveal_type
def foo(x: tuple[str, str] | tuple[str, str, str] | dict[str, str] | None) -> None:
reveal_type(x)
match x:
case (a, b):
reveal_type(x)
print("pair")
case {"a": "1"}:
reveal_type(x)
print("a1 dict")
case {}:
reveal_type(x)
print("dict from {}")
case dict():
reveal_type(x)
print("dict from dict()")
foo(("a", "b"))
foo({"a": "1"})
foo({"a": "2"})
```
pyright 1.1.407 reports:
```
typecheck.py:4:17 - information: Type of "x" is "tuple[str, str] | tuple[str, str, str] | dict[str, str] | None"
typecheck.py:7:25 - information: Type of "x" is "tuple[str, str]"
typecheck.py:10:25 - information: Type of "x" is "dict[str, str]"
typecheck.py:13:25 - information: Type of "x" is "tuple[str, str, str] | dict[str, str] | None"
typecheck.py:16:25 - information: Type of "x" is "dict[str, str]"
```
Whereas running the script confirms that the `{}` branch is indeed taken by the 3rd call:
```
$ python3 src/a14y/typecheck.py
Runtime type is 'tuple'
Runtime type is 'tuple'
pair
Runtime type is 'dict'
Runtime type is 'dict'
a1 dict
Runtime type is 'dict'
Runtime type is 'dict'
dict from {}
```
Thus I expect we should see instead:
```
typecheck.py:4:17 - information: Type of "x" is "tuple[str, str] | tuple[str, str, str] | dict[str, str] | None"
typecheck.py:7:25 - information: Type of "x" is "tuple[str, str]"
typecheck.py:10:25 - information: Type of "x" is "dict[str, str]"
typecheck.py:13:25 - information: Type of "x" is "dict[str, str]"
```
(line 16 not being emitted, as is the case for other unreachable patterns)
Contributor guide
Research direction
Start with the reproducer in src/a14y/typecheck.py and run it with pyright 1.1.407 to confirm the current narrowing and unreachable-pattern diagnostics. Trace the match/case type-inference behavior for the {} pattern, then verify that x narrows to dict[str, str] in that branch and that the later dict() branch is reported 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