更改子类的 python 类型提示

Changing python type hints for subclasses

设想以下代码使用基 class 和 DAG subclass 处理图形:

class NodeBase:
    def some_node_func(self):
        pass

class GraphBase:
    def add(self, node: NodeBase):
        node.some_node_func()

class DirectedNode(NodeBase):
    def some_dag_func(self):
        pass

class DirectedGraph(GraphBase):
    def add(self, node: DirectedNode):
        node.some_node_func()
        node.some_dag_func()

当我尝试将此代码与 mypy 一起使用时,出现如下错误:

error: Argument 1 of "add" is incompatible with supertype "GraphBase"; 
supertype defines the argument type as "NodeBase"  [override]

我的问题表面上与 Python: how to handle type hinting in subclasses? 相似,但实际上我需要与依赖相应 DirectedNode 功能的 DirectedGraph.add 函数不同的行为。

我意识到这“违反了 Liskov 替换原则”,但我不需要能够将 DirectedNode 个实例添加到非 DAG 图。

我怎样才能构造这样的东西,这样 mypy 就不会抱怨?如果可能的话,我想避免只禁用检查。

参数化 GraphBase 用于表示节点的类型,而不是对 NodeBase

的硬编码引用
from typing import Generic, TypeVar


N = TypeVar('N', bound=NodeBase)


class NodeBase:
    def some_node_func(self):
        pass

class GraphBase(Generic[N]):
    def add(self, node: N):
        node.some_node_func()

class DirectedNode(NodeBase):
    def some_dag_func(self):
        pass

class DirectedGraph(GraphBase[DirectedNode]):
    def add(self, node: DirectedNode):
        node.some_node_func()
        node.some_dag_func()