Skip to content

Commit 6230a25

Browse files
committed
Use first argument in super
1 parent 5e74d53 commit 6230a25

File tree

2 files changed

+40
-15
lines changed

2 files changed

+40
-15
lines changed

tests/snippets/class.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,19 @@ def test1(self):
7575
assert c.test() == 100
7676
assert c.test1() == 200
7777

78+
class Me():
79+
80+
def test(me):
81+
return 100
82+
83+
class Me2(Me):
84+
85+
def test(me):
86+
return super().test()
87+
88+
me = Me2()
89+
assert me.test() == 100
90+
7891
a = super(bool, True)
7992
assert isinstance(a, super)
8093
assert type(a) is super

vm/src/obj/objsuper.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ https://github.com/python/cpython/blob/50b48572d9a90c5bb36e2bef6179548ea927a35a/
77
*/
88

99
use crate::function::PyFuncArgs;
10+
use crate::obj::objstr;
1011
use crate::obj::objtype::PyClass;
1112
use crate::pyobject::{
1213
DictProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
@@ -75,7 +76,11 @@ fn super_getattribute(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
7576
return Ok(vm.ctx.new_bound_method(item, inst.clone()));
7677
}
7778
}
78-
Err(vm.new_attribute_error(format!("{} has no attribute '{}'", inst, name_str)))
79+
Err(vm.new_attribute_error(format!(
80+
"{} has no attribute '{}'",
81+
inst,
82+
objstr::get_value(name_str)
83+
)))
7984
}
8085
_ => panic!("not Class"),
8186
}
@@ -94,14 +99,31 @@ fn super_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
9499
return Err(vm.new_type_error(format!("{:?} is not a subtype of super", cls)));
95100
}
96101

102+
// Get the bound object:
103+
let py_obj = if let Some(obj) = py_obj {
104+
obj.clone()
105+
} else {
106+
let frame = vm.current_frame();
107+
if let Some(first_arg) = frame.code.arg_names.get(0) {
108+
match vm.get_locals().get_item(first_arg) {
109+
Some(obj) => obj.clone(),
110+
_ => {
111+
return Err(vm
112+
.new_type_error(format!("super arguement {} was not supplied", first_arg)));
113+
}
114+
}
115+
} else {
116+
return Err(vm.new_type_error(
117+
"super must be called with 1 argument or from inside class method".to_string(),
118+
));
119+
}
120+
};
121+
97122
// Get the type:
98123
let py_type = if let Some(ty) = py_type {
99124
ty.clone()
100125
} else {
101-
match vm.get_locals().get_item("self") {
102-
Some(obj) => obj.typ().clone(),
103-
_ => panic!("No self"),
104-
}
126+
py_obj.typ().clone()
105127
};
106128

107129
// Check type argument:
@@ -113,16 +135,6 @@ fn super_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
113135
)));
114136
}
115137

116-
// Get the bound object:
117-
let py_obj = if let Some(obj) = py_obj {
118-
obj.clone()
119-
} else {
120-
match vm.get_locals().get_item("self") {
121-
Some(obj) => obj,
122-
_ => panic!("No self"),
123-
}
124-
};
125-
126138
// Check obj type:
127139
if !(objtype::isinstance(&py_obj, &py_type) || objtype::issubclass(&py_obj, &py_type)) {
128140
return Err(vm.new_type_error(

0 commit comments

Comments
 (0)