python / python/typing

When making a dynamic member descriptor that can also behave as a Wrapper Why Does Self Not get deleted from ParamSpec?

オープン
#2,060 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

topic: other
主要言語
Python
スター
1.8k
フォーク
302
平均マージ
23時間
マージ済み PR(30日)
8

説明

I've bumped into one of the largest and most frustrating puzzles I've ever encountered but I wanted to understand what the thought process behind ParamSpec was for class functions because I think if Self was ignored from ParamSpec dynamically based on weather or not a class function was in use it would not only fix lru_cache but it would also allow async_lru library to be type-hinted as well. No matter what I do, nothing works. I've tried multiple search engines to no avail so I go here now as my final resort since it's not a mypy problem because pyright is also plagued by the same rules.


from typing import ParamSpec, TypeVar, Callable, Protocol

P = ParamSpec("P")
T = TypeVar("T")
I = TypeVar("I")

# I made a class of my own for callable to illistrate the problem at hand.
class CallableProto(Protocol[P, T]):
    def __call__(self, *args:P.args, **kwds:P.kwargs) -> T:...

class RespectingCallable(CallableProto[P, T]):
    def __init__(self, func:Callable[P, T]):
        self.func = func
    # My question is Why does Self inside of a class function still get preserved in 
    # ParamSpec when it's just a class function? Shouldn't it get removed?
    # Also Concatenate doesn't work I've tried that one already with no success...
    def __get__(self, instance:I, obj:type[I]) -> CallableProto[P, T]:...

class A:
    def __init__(self) -> None:
        pass
    @RespectingCallable
    def coro(self, val:int) -> str:
        return f"{val}"

g = A()
# It appears as (self: A, val: int) -> str instead of (val: int) -> str 
# (mypy and pyright are also both are plagued by these rules)
g.coro(1)

@RespectingCallable
def func(i:int) -> str:
    return f"{i}"
# Somehow this is fine?
func(1)

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

提供された Python の例から始め、ParamSpec、Self、Concatenate、および descriptor binding のルールを確認します。mypy と pyright がその例をどのように解釈するかを比較し、意図した結果に仕様の明確化またはドキュメントの変更が必要かどうかを判断します。動作と期待されるアノテーションが明確に決定されれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
developer-experience
issue の種類
ドキュメント
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
説明が足りない
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。