mypy:サブクラスメソッドに異なるkwargsがある場合の型コメント

mypy:サブクラスメソッドに異なるkwargsがある場合の型コメント

抽象基本クラスにメソッドがあり、サブクラスがそのメソッドを実装していくつかのオプションのキーワード引数を追加する場合、既存のコードに型コメントを追加する問題に何度も遭遇しました。コードが次のようになるとします。

class Base:
    def foo(self, x: int, **kwargs) -> None: ...

class A(Base):
    def foo(self, x: int, *, frob: bool = False) -> None: ...

class B(Base):
    def foo(self, x: int, *, extra: str = '') -> None: ...

Mypyは、サブクラスの実装が基本クラスより一般的ではないため、これを拒否します(任意のキーワード引数を受け入れないため)。

kwargs基本クラスからを削除することができますが、これを行うと、Baseすべてのインスタンスを受け入れ、次のように任意のキーワード引数を渡す関数に問題が発生する可能性があります。

def call_base(x: Base, **kwargs) -> None:
    x.foo(3, **kwargs)

これにより、Base.fooが任意のキーワード引数を受け入れないため、Mypyは文句を言います。

もう1つのオプションは、派生クラスの実装に(unused)を採用させることですが、kwargsこれも欠点があります。

  • 精度が低下するため、インスタンスが派生クラスの1つに属することが(静的に)知られている場合、mypyはあまり役に立ちません。
  • ユーザーが無効なキーワード引数を渡すと、例外を発生させるのではなく自動的に無視されます(これを確認するために追加のコードが追加されない限り)。

ケーキを食べても食べることができる方法はありますか?つまり、基本クラスから呼び出されたときに追加の引数をチェックせずに、代わりに派生クラスでチェックするようにmypyに指示しますか?これは型モデルに違反すると思うかもしれませんが(派生クラスメソッドは許可されたパラメータの範囲を絞り込むことはできません)、すでに単一のパラメータに対して可能です(基本クラスでは宣言しますがAny派生クラス型では具体的に宣言)。

ベストアンサー1

おすすめ記事