generics are removed from function signatures that are assigned to `Callable` types
オープン
まだ誰も着手していません。
bug
- 主要言語
- Python
- スター
- 20.6k
- フォーク
- 3.3k
- PR マージ指標
- PR 指標を取得中
説明
from typing import TypeVar, Callable
T = TypeVar("T")
def asdf(fn: Callable[[], T]) -> Callable[[], T]: ...
@asdf
def foo() -> list[T]: ...
reveal_type(foo) # "def () -> list[Never]", should be "def [T] () -> list[T]"
use case
i'm making a @NoInstance decorator that bans usages of classmethods on instances:
from typing import TypeVar, ParamSpec, Concatenate, Callable, Generic, overload, Never
out_T = TypeVar("out_T", covariant=True)
P = ParamSpec("P")
out_R = TypeVar("out_R", covariant=True)
class NoInstance(Generic[P, out_R]):
def __init__(self, function: Callable[Concatenate[type[out_T], P], out_R]):
...
@overload
def __get__(self, instance: None, owner: type[object]) -> Callable[P, out_R]:
...
@overload
def __get__(self, instance: object, owner: type[object]) -> Never:
...
def __get__(self, instance: object, owner: type[object]) -> object:
...
class Foo:
@NoInstance
@classmethod
def foo(cls):
...
Foo.foo() # allowed
Foo().foo() # not allowed
but the primary use case for class methods that should not be called on instances are constructor methods, which means the resulting signature only has the typevar on the return type (in this case, Self):
class Foo:
@NoInstance
@classmethod
def from_int(cls) -> Self:
...
reveal_type(Foo.from_int) # `"def () -> Never"`, because the `Self` generic was removed by the `Concatenate`. should be `def () -> Foo` instead
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
リンクされた mypy playground で最小限の例を実行し、表示された型を期待されるジェネリックシグネチャと比較することから始めます。これらの例に関係する型推論と Callable/Concatenate の処理を追跡します。完了の条件は、ジェネリックな T または Self が Never に縮約されずに保持されることです。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- devtools
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- 明確に書かれている
- 初心者へのやさしさ
- 42/100