Reject conflicting member layouts in multiple inheritance (#9041)

Extract the Python 3.14-compatible solid-base check from #8954. Prefix member cells contribute to instance layout even though they do not change basicsize. Include member_count in shape comparison while preserving all native layout safeguards, and cover conflicting and compatible bases in the existing type snippet.

Assisted-by: OpenAI Codex:model identifier unavailable
This commit is contained in:
youknowdot authored and GitHub committed 2026-10-10 19:34:12 +09:00
1 parent 5dba000d8b
commit 9c8b745bfe
2 files changed
+55 -1

No files matched your search

+5 -1
View File
@@ -3677,7 +3677,11 @@ fn mro_internal(typ: &Py<PyType>, vm: &VirtualMachine) -> PyResult<i32> {
/// Returns true if the two types have different instance layouts.
fn shape_differs(t1: &Py<PyType>, t2: &Py<PyType>) -> bool {
t1.slots.basicsize != t2.slots.basicsize || t1.slots.itemsize != t2.slots.itemsize
// Prefix member cells do not change basicsize, but still make a base
// solid: unrelated slotted bases cannot share the same member indexes.
t1.slots.basicsize != t2.slots.basicsize
|| t1.slots.itemsize != t2.slots.itemsize
|| t1.slots.member_count != t2.slots.member_count
}
fn solid_base<'a>(typ: &'a Py<PyType>, vm: &VirtualMachine) -> &'a Py<PyType> {
+50
View File
@@ -748,3 +748,53 @@ with warnings.catch_warnings():
warnings.simplefilter("error")
with assert_raises(RuntimeWarning):
type("NonStringKeyRaises", (), {6: 7})
class Left:
__slots__ = ("left",)
class Right:
__slots__ = ("right",)
with assert_raises(TypeError):
class Conflict(Left, Right):
pass
with assert_raises(TypeError):
class ReverseConflict(Right, Left):
pass
class Empty:
__slots__ = ()
class Compatible(Left, Empty):
pass
value = Compatible()
value.left = 42
assert value.left == 42
class FirstChild(Left):
__slots__ = ()
class SecondChild(Left):
__slots__ = ()
class Diamond(FirstChild, SecondChild):
pass
value = Diamond()
value.left = 43
assert value.left == 43