Resolution / determining of metaclass docs don't align with what really happens
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 36k
- PR 合并指标
- PR 指标待抓取
描述
Documentation
I'm not 100% sure if this is an issue with the docs or the interpreter. But it's evident that the docs don't match what the interpreter does.
The docs say here:
The appropriate metaclass for a class definition is determined as follows:
- if no bases and no explicit metaclass are given, then :func:
typeis used;- if an explicit metaclass is given and it is not an instance of
:func:type, then it is used directly as the metaclass;- if an instance of :func:
typeis given as the explicit metaclass, or
bases are defined, then the most derived metaclass is used.The most derived metaclass is selected from the explicitly specified
metaclass (if any) and the metaclasses (i.e.type(cls)) of all specified
base classes. The most derived metaclass is one which is a subtype of all
of these candidate metaclasses. If none of the candidate metaclasses meets
that criterion, then the class definition will fail withTypeError.
So according to that, the metaclass of D in this code
class M1(type): pass
class M2(type): pass
class Mx(M1, M2): pass
class A1(metaclass=M1): pass
class A2(A1): pass
class B1(metaclass=M2): pass
class C1(metaclass=Mx): pass
class D(A2, B1, C1): pass
should be Mx as it's the most derived of all candidates (M1, M2, Mx). But instead the cpython exitis with
class D(A2, B1, C1): pass
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
Note that class D(A2, C1, B1): pass works.
Some additional context:
- I was investigating a false positive metaclass conflict reported by mypy when I came across this
- This piece of docs seems to origin from way back in 2005, issue #42380
As said above, I'm not even sure what the actually algorithm is that determines the implicit metaclass. From my experimentation, I assume it's:
- If there's an explicit metaclass, it is checked to be a sub-class of the metaclass of each parent
- If there's no explicit metaclass, the parents are checked from left to right:
- When a new metaclass is encountered, it is checked to be a sub-class of the previous implicit metaclass and, if it is, set as the new implicit metaclass.
Linked PRs
- gh-123349
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 Doc/reference/datamodel.rst 中的元类部分开始,并在 CPython 下运行所提供的类定义示例,以比较文档所述行为与实际观察到的行为。查看链接的 PR gh-123349 以及其中引用的历史 issue,以了解当前的调查。完成的标准是解释器行为与文档得到协调,并有明确的解决方案。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- documentation
- Issue 类型
- 文档
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 25/100