Static protocols' (`type[IFoo[T]]]`) type parameters (`T`) are unknown
- Dominant language
- Python
- Stars
- 15.6k
- Forks
- 1.8k
- Avg merge
- 12h 13m
- Merged PRs (30d)
- 52
Description
Basically `type[IFoo[T]]` causes `T` to become `Unknown`, where `IFoo[T]` doesn't. The problem is I'm passing a type not an instance so any `issubclass` checks then are invalid.
[Pyright Playground link](https://pyright-play.net/?strict=true&code=GYJw9gtgBALgngBwJYDsDmUkQWEMoAK4MYAxmADYBQNpFAhgM6NQCSAYmGANoAqAugAoiYEuQoBKAFxUocqAAE6TRhACmMABZgAJrPk61wKBDgB9dVt2C6jADRQAbvQoBXNVKi8JUALQA%2BKAA5MBQPKAA6KJoqZWYoTh4BQQ4uPn5pfTklBmZLbT15KENjUwsNApsKeycXd09vP0CQsM8oiJi4ll41RhhWFD76FFI1dJkikqgzM1QkGBnBRjUKYAdSJhhPVKSMpuDQ8PbO3O7emABhU-Gs4qNp2ZR5xeXV9c3PeAQxnfS9gIOrUi0RowAADFAALxec4DIYjNSCRISKjAACMUJhfSuKiRXBRQA).
```python
from typing import Protocol
class IFoo[T](Protocol):
@classmethod
def my_method(cls, value: T) -> None: ...
class Foo[T](IFoo[T]):
@classmethod
def my_method(cls, value: T) -> None: ...
class TestInstance[T]:
def __init__(self, interface: IFoo[T]) -> None: ...
class TestClass[T]:
def __init__(self, interface: type[IFoo[T]]) -> None: ...
f0 = TestInstance(Foo)
f1 = TestClass(Foo) # Type of "f1" is "TestClass[Unknown]" (reportUnknownVariableType)
```
To get the `issubclass` checks to work I then have to immediately cast to the correct type: `interface = cast(type[IFoo[T]], interface)`.
Oddly when using `@overload` with multiple static interfaces `type` matches correctly. Just the type parameters aren't set correctly. Using `IFoo` rather than `type[IFoo]` causes wrong matches.
Contributor guide
Research direction
Start with the linked Pyright Playground reproduction and compare inference for TestInstance(Foo) with TestClass(Foo), focusing on the static protocol type parameter T. Done means TestClass(Foo) no longer infers Unknown and the resulting type supports the intended issubclass checks without the reported cast.
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