mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 10:44:36 +08:00
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:
1 parent
5dba000d8b
commit
9c8b745bfe
2 files changed
+55
-1
No files matched your search
@@ -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> {
|
||||
|
||||
@@ -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
|
||||
Reference in new issue
Block a user