`mypy` doesn't understand that `*args: P.args` implies that `args` is a `tuple`
オープン
まだ誰も着手していません。
bug
topic-calls
topic-paramspec
- 主要言語
- Python
- スター
- 20.6k
- フォーク
- 3.3k
- PR マージ指標
- PR 指標を取得中
説明
from typing import Callable
def as_tuple[*Ts](*args: *Ts) -> tuple[*Ts]: return args
def tuple_identity[*Ts](t: tuple[*Ts]) -> tuple[*Ts]: return t
def tuple_identity2[T: tuple](t: T) -> T: return t
def test_paramspec[**P](
dummy: Callable[P, None], # ensure P is bound
/,
*args: P.args,
**kwargs: P.kwargs,
) -> None:
reveal_type(args) # N: "P.args`-1"
reveal_type( (*args,) ) # N: "builtins.tuple[P.args`-1, ...]"
reveal_type( tuple(args) ) # N: "builtins.tuple[builtins.object, ...]"
reveal_type(as_tuple(*args)) # N: "builtins.tuple[P.args`-1, ...]"
reveal_type(tuple_identity(args)) # N: "builtins.tuple[Never, ...]"
# E: [arg-type]
reveal_type(tuple_identity2(args)) # N: "P.args`-1" ✅
if isinstance(args, tuple):
pass
else:
reveal_type(args) # false negative [warn-unreachable]
Ideally, all the reveal_types should show the same result (or raise errors if considered misuse of ParamSpec[^1]), and the else-branch should trigger an unreachable warning.
[^1]: For instance, pyright says as_tuple(*args) is illegal. Code sample in pyright playground
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
提供されている test_params の再現コードから始め、warn-unreachable を有効にして実行し、mypy の reveal_type の結果を期待される動作およびリンクされた playground と比較します。mypy における ParamSpec args の処理と tuple の narrowing を追跡します。reveal type が一貫しているか正しく拒否され、到達不能な else 分岐が到達不能として報告されれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- devtools
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 42/100