python / python/mypy

Protocol incorrectly matches when positional or keyword parameter matches *args

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

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

bug
主要言語
Python
スター
20.6k
フォーク
3.3k
PR マージ指標
PR 指標を取得中

説明

Bug Report

When a protocol defines a function with a keyword or positional parameter (a: int) -> None, a concrete function where said parameter is missing, but matches the *args parameter (*args: int) -> None will be seen as implementing the protocol.

I would expect (a: int) -> None to also need matching **kwargs such as (*args: int, **kwargs: int) -> None and for it to only match *args alone when specified as a positional only argument (e.g. (a: int, /) -> None)

Otherwise it cannot be called safely, pyright and ty both successfully raise errors for this case.

To Reproduce

https://mypy-play.net/?mypy=master&python=3.14&flags=strict&gist=a5f86e32e70cbc84c45a53db5426f78f

Expected Behavior

main.py:13: error: Argument 1 to "f" has incompatible type "C"; expected "P"  [arg-type]

because calling the method as foo(a=1) would fail.

Actual Behavior

mypy:

Success: no issues found in 1 source file

pyright:

Argument of type "C" cannot be assigned to parameter "o" of type "P" in function "f"
  "C" is incompatible with protocol "P"
    "foo" is an incompatible type
      Type "(*args: int) -> None" is not assignable to type "(a: int) -> None"
        Missing keyword parameter "a"  (reportArgumentType)

ty:

Argument to function `f` is incorrect: Expected `P`, found `C` (invalid-argument-type) [Ln 17, Col 3]

python:

Traceback (most recent call last):
  File "xxx.py", line 17, in <module>
    f(C())
    ~^^^^^
  File "xxx.py", line 14, in f
    o.foo(a=1)
    ~~~~~^^^^^
TypeError: C.foo() got an unexpected keyword argument 'a'

Your Environment

  • Mypy version used: 1.19.1 and master
  • Mypy command-line flags: --strict
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 1.14

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

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

はじめの一歩

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

調査の方向性

リンクされた mypy-play の例を mypy master、Python 3.14、--strict を使って再現します。示されている foo のシグネチャについて、プロトコル互換性の処理を追跡し、結果を pyright および ty と比較します。mypy が想定される incompatible-protocol エラーを報告し、positional-only のケースを維持できれば完了です。

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

評価

技術スタック
python
領域
devtools
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
42/100

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

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