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

为何错误MRO无法被mypy等静态类型检查器检测?

关于Python中Protocol、Generic继承顺序导致MRO错误及mypy检查通过的疑问

问题场景

以下代码在运行时会触发方法解析顺序(MRO)相关错误:

from dataclasses import dataclass
from typing import Generic, Protocol, TypeVar

T = TypeVar("T")


class HasFoo(Protocol):
    foo: str


class Mixin(HasFoo):
    foo = "test"


@dataclass()
class MyClass(Generic[T], Mixin):
    t: T

运行时错误信息

执行上述代码后,抛出如下错误:

Traceback (most recent call last):
  File "/home/veith/.config/JetBrains/PyCharm2022.2/scratches/scratch_4.py", line 16, in <module>
    class MyClass(Generic[T], FooMixin):
  File "/home/veith/.pyenv/versions/3.8.3/lib/python3.8/abc.py", line 85, in __new__
    cls = super().__new__(mcls, name, bases, namespace, **kwargs)
TypeError: Cannot create a consistent method resolution
order (MRO) for bases Generic, Mixin

相关测试与猜测

我猜测该问题与Protocol接收泛型参数的机制有关,测试了几种泛型Protocol的写法:

# 标准泛型Protocol写法
class HasT(Protocol[T]):
    t: T

# 等价的语法糖形式
class HasT(Protocol, Generic[T]):
    t: T

# 颠倒Generic与Protocol顺序的写法,未触发错误
class HasT(Generic[T], Protocol):
    t: T

查阅PEP 544中关于泛型Protocol的章节,未找到相关说明。

解决方法

只需颠倒MyClass的继承顺序即可解决问题:

@dataclass()
class MyClass(Mixin, Generic[T]):
    t: T

核心疑问

  1. 为何继承顺序会引发MRO不一致的错误?已知Generic无父类,Protocol继承自Generic,理论上继承树存在循环依赖,但具体为何会导致MRO冲突?
  2. 为何mypy 0.980能够通过对原错误代码的类型检查,未识别出该问题?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:25:38