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가 불평할 것입니다.

또 다른 옵션은 파생 클래스 구현이 (unused) 를 채택하도록 하는 것이지만 kwargs이 역시 단점이 있습니다.

  • 정확도가 떨어지므로 인스턴스가 파생 클래스 중 하나에 속하는 것으로 (정적으로) 알려진 경우 mypy는 덜 유용합니다.
  • 사용자가 잘못된 키워드 인수를 전달하면 이제 예외를 발생시키는 대신 자동으로 무시됩니다(이를 확인하기 위해 추가 코드가 추가되지 않는 한).

케이크를 먹고도 먹을 수 있는 방법이 있나요? 즉, 기본 클래스에서 호출될 때 추가 인수를 확인하지 않고 대신 파생 클래스에서 확인하도록 mypy에 지시합니까? 이것이 유형 모델을 위반한다고 생각할 수도 있지만(파생 클래스 메소드는 허용되는 매개변수의 범위를 좁힐 수 없음) 이미 단일 매개변수에 대해 가능합니다( Any기본 클래스에서는 선언하지만 파생 클래스 유형에서는 구체적으로 선언).

관련 정보