抽象基本クラスにメソッドがあり、サブクラスがそのメソッドを実装していくつかのオプションのキーワード引数を追加する場合、既存のコードに型コメントを追加する問題に何度も遭遇しました。コードが次のようになるとします。
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
派生クラス型では具体的に宣言)。