Skip to content

Commit 8077e98

Browse files
authored
Merge pull request #3058 from youknowone/super-getattro
revise PySuper::getattro same as CPython super_getattro
2 parents b12300e + cfc5163 commit 8077e98

1 file changed

Lines changed: 19 additions & 9 deletions

File tree

‎vm/src/builtins/pysuper.rs‎

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,27 +123,37 @@ impl PySuper {
123123

124124
impl SlotGetattro for PySuper {
125125
fn getattro(zelf: PyRef<Self>, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
126-
let (inst, obj_type) = match zelf.obj.clone() {
126+
let skip = |zelf: PyRef<Self>, name| vm.generic_getattribute(zelf.into_object(), name);
127+
let (obj, start_type): (PyObjectRef, PyTypeRef) = match zelf.obj.clone() {
127128
Some(o) => o,
128-
None => return vm.generic_getattribute(zelf.into_object(), name),
129+
None => return skip(zelf, name),
129130
};
130-
// skip the classes in obj_type.mro up to and including zelf.typ
131-
let it = obj_type
131+
// We want __class__ to return the class of the super object
132+
// (i.e. super, or a subclass), not the class of su->obj.
133+
134+
if name.as_str() == "__class__" {
135+
return skip(zelf, name);
136+
}
137+
138+
// skip the classes in start_type.mro up to and including zelf.typ
139+
let mro: Vec<_> = start_type
132140
.iter_mro()
133141
.skip_while(|cls| !cls.is(&zelf.typ))
134-
.skip(1);
135-
for cls in it {
142+
.skip(1) // skip su->type (if any)
143+
.collect();
144+
for cls in mro {
136145
if let Some(descr) = cls.get_direct_attr(name.as_str()) {
137146
return vm
138147
.call_get_descriptor_specific(
139148
descr.clone(),
140-
if inst.is(&obj_type) { None } else { Some(inst) },
141-
Some(obj_type.clone().into_object()),
149+
// Only pass 'obj' param if this is instance-mode super (See https://bugs.python.org/issue743267)
150+
if obj.is(&start_type) { None } else { Some(obj) },
151+
Some(start_type.as_object().clone()),
142152
)
143153
.unwrap_or(Ok(descr));
144154
}
145155
}
146-
vm.generic_getattribute(zelf.into_object(), name)
156+
skip(zelf, name)
147157
}
148158
}
149159

0 commit comments

Comments
 (0)