microsoft / microsoft/pyright

No narrowing after `isinstance(obj, tuple)` if `tuple` contains a term.

Open
#10,916 3 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

**Describe the bug**
The type narrowing of `isinstance(obj, class_or_tuple, /)` doesn't happen if one of the classes in `class_or_tuple` is not just a type, but a term.

I understand that we can't have dependent types, but in this example, I expect `C` to have been removed from the inferred type of `x` afer the `isinstance` has returned False. `C | T ∧ ¬C` or if the term cannot be statically inferred ` C | Unknown ^ ¬C`

**Code or Screenshots**

Code sample in [pyright playground](https://pyright-play.net/?pythonVersion=3.12&code=GYJw9gtgBALgngBwJYDsDmUkQWEMpRoCmMA%2BrkmqgDRQCGAzg0XqSkQG4sBQ3AxgBtGDKAGEAXNwIEEw3gBMiwKMADaAFQC6ACmYDgtAB7ixUAD5R1tGCfgIiGzQEpJ02Cwi3ERKAF5CJOQglKja6k5QuLBS0kjKSAyoDDB0KHxE2oa02qLWHk4uMW4EICQAriAoUABidALMRZjxiSjJqemZtKKFxdLCLGTsXCDaTtxAA)

```python
from typing import get_origin, assert_never

class C:
pass

def f[T](self, x: C | T, t: type[T]):
term: type = get_origin(T) or t
if isinstance(x, (C, term)):
return False
if isinstance(x, C):
assert_never()

```

note that the second `isinstance` is only to show the problem, not an actual use case.

Contributor guide

Open the contributing guide

Research direction

Reproduce the example in the linked pyright playground with Python 3.12 and inspect the narrowing after the first isinstance check. Trace the type-analysis entry point for isinstance expressions and determine whether the false branch removes C when the tuple contains the term. Done means the second isinstance branch is recognized as unreachable in this example, with appropriate regression coverage.

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
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.