You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现抽象方法时扩展输入参数,mypy提示‘Signature of "<func_name>" incompatible with supertype "<base_class>" [override]’错误的原因咨询

Why does mypy flag my subclass method override as incompatible when adding a required parameter?

Let's break down why mypy is complaining and how to fix this issue clearly.

The Root Cause: Liskov Substitution Principle

Your error stems from violating a core object-oriented design rule called the Liskov Substitution Principle (LSP). This principle requires that any subclass should be usable in place of its parent class without breaking the program's logic.

Looking at your code:

  • The parent class Strategies defines compute_signls to accept zero or more positional arguments (*args: Any). That means code expecting a Strategies instance could legally call obj.compute_signls() with no parameters.
  • But your subclass MyStrategy changes this to require a mandatory first argument indicator: pd.DataFrame. Now, if that same code tried to call MyStrategy().compute_signls() (without the indicator), it would crash immediately.

Mypy catches this mismatch because it enforces that subclass method signatures are contravariant—subclass methods can't require more arguments than the parent, only accept fewer or the same set.

Fixes to Try

Option 1: Make the subclass parameter optional (with a default value)

This keeps compatibility with the parent class signature while still allowing your subclass to use the parameter. You'll just need to handle the case where the parameter isn't provided:

class MyStrategy(Strategies):
    def compute_signls(
        self, indicator: pd.DataFrame | None = None, *args: Any, **kwargs: Any
    ) -> dict[str, pd.DataFrame]:
        if indicator is None:
            raise ValueError("MyStrategy requires an indicator parameter to compute signals")
        # Rest of your signal logic here
        pass

Option 2: Update the parent class to require the parameter

If all strategies you plan to implement need an indicator, then the parent class should enforce this requirement in its abstract method. This makes the signature consistent across parent and child:

class Strategies(ABC):
    def __init__(self, price: pd.Series | pd.DataFrame) -> None:  # Fixed typo: missing parentheses on __init__
        self.price = price

    @abstractmethod
    def compute_signls(self, indicator: pd.DataFrame, *args: Any, **kwargs: Any) -> dict[str, pd.DataFrame]:
        """Compute signals"""

(Note: I also fixed a typo in your parent class __init method—you had __init(self, ...) instead of __init__(self, ...))

Option 3: Use a Protocol for stricter subclasses (advanced)

If you need some strategies to work without an indicator and others to require it, you can split this into separate protocols. This lets you enforce different requirements for different strategy types:

from typing import Protocol

class BaseStrategy(ABC):
    @abstractmethod
    def compute_signls(self, *args: Any, **kwargs: Any) -> dict[str, pd.DataFrame]:
        pass

class IndicatorRequiredStrategy(Protocol):
    def compute_signls(self, indicator: pd.DataFrame, *args: Any, **kwargs: Any) -> dict[str, pd.DataFrame]:
        pass

class MyStrategy(BaseStrategy, IndicatorRequiredStrategy):
    def compute_signls(
        self, indicator: pd.DataFrame, *args: Any, **kwargs: Any
    ) -> dict[str, pd.DataFrame]:
        pass

This is more flexible but adds complexity, so only use it if you need to support both types of strategies.

Quick Side Note

You might want to fix the typo in your method name: compute_signls should probably be compute_signals—it'll avoid confusion down the line!

内容的提问来源于stack exchange,提问作者Andi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 15:17:35