microsoft / microsoft/pyright

Incorrect reachability analysis involving NewType

Open
#10,678 2 comments 3 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

With this program ([playground](https://pyright-play.net/?pythonVersion=3.13&strict=true&locale=en&enableExperimentalFeatures=true&code=GYJw9gtgBALgngBwJYDsDmUkQWEMoByApgO4AqiRAsAFC0FlQC8hpFCRAFAEQPcA0UAM4wQASlq0AxgBsAhkKFQAGpxHiAXLSg6oCBUMk0AJkWBRgnAB4bCZMVpq7M5pENQi5KKVyuDlDtrOuiBEAG5EcjIA%2BvAc1hJOukQyQkSOwSHhkTFxvom0lgycqtxW3GKVtEA)):

```python
from typing import NewType

NT = NewType("NT", str)

class X(str):
pass

def f(x: NT):
if isinstance(x, X):
reveal_type(x)
else:
reveal_type(x)

f(NT(X("x")))
```

Pyright reports `Unnecessary isinstance call; "NT" is never an instance of "X"`. This is incorrect, as the underlying value of the NewType may be an instance of a subclass of str.

Mypy correctly creates an ad-hoc intersection here and reports `Revealed type is "__main__."`.

Contributor guide

Open the contributing guide

Research direction

Start with the linked playground reproducer and inspect the reachability analysis for isinstance narrowing of a NewType, comparing the result with the shown mypy behavior. Done means Pyright no longer reports the isinstance call as unreachable and preserves the possible subclass in both reveal_type results.

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.