Different narrowing with `isinstance` vs match-case against Callback-Protocol
- Dominant language
- Python
- Stars
- 15.6k
- Forks
- 1.8k
- Avg merge
- 12h 13m
- Merged PRs (30d)
- 52
Description
Code sample in [pyright playground](https://pyright-play.net/?reportUnreachable=true&code=GYJw9gtgBALgngBwJYDsDmUkQWEMoDCAhgDYlEBGJApgDRQAK4MYAxmCfSAK4oxbUA%2BqwAW1VgGtKNegEEUcLtQBu1UoPgJqAKG0ABHnwHCxk6TtbkAzlajy4xMuYAUTMC3YkAlAC5tUAKgAE2pgKEFhUhII5ytqEmB6ACoiEDQrHzsFZKSJAHdU9Mz7LygAWgA%2BLLhMgDp63RCwmGorGEEAZmdgFEzHcipqAG0h1BgAXXox8dLKqAA5MBRqP0DMMKQrVDaiFFZqbpQ5BX7zX381wJAVNWjNA57SqABiTD5yqrHG0NhW9oA2Q59KLmEbTKZ8GYfBZLFYXAIQIgwURQHqrS4BVhEOLVU6DZylbGo3rwjFXG7qe6HJ6vXjXIiiczaIA)
```python
from typing import Callable, Protocol, runtime_checkable, Any, reveal_type
@runtime_checkable
class AnyCallable(Protocol):
def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
def test_3(fn: Callable[[int], int]) -> None:
if isinstance(fn, AnyCallable):
reveal_type(fn) # int -> int
def test_6(fn: Callable[[int], int]) -> None:
match fn:
case AnyCallable() as fn:
reveal_type(fn) # unreachable
```
I would have expected the same `reveal_type` result in both cases.
Contributor guide
Research direction
Start with the linked Pyright playground reproduction and compare the narrowing behavior in test_3 and test_6, focusing on the isinstance and match-case entry points. Done means the match-case branch is handled consistently with the isinstance branch and the reveal_type result is no longer considered unreachable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100