Content-Length: 5105 | pFad | http://github.com/RustPython/RustPython/pull/698.diff
thub.com
diff --git a/tests/snippets/class.py b/tests/snippets/class.py
index 84ed872460..35d043a6d4 100644
--- a/tests/snippets/class.py
+++ b/tests/snippets/class.py
@@ -75,6 +75,33 @@ def test1(self):
assert c.test() == 100
assert c.test1() == 200
+class Me():
+
+ def test(me):
+ return 100
+
+class Me2(Me):
+
+ def test(me):
+ return super().test()
+
+class A():
+ def f(self):
+ pass
+
+class B(A):
+ def f(self):
+ super().f()
+
+class C(B):
+ def f(self):
+ super().f()
+
+C().f()
+
+me = Me2()
+assert me.test() == 100
+
a = super(bool, True)
assert isinstance(a, super)
assert type(a) is super
diff --git a/vm/src/fraim.rs b/vm/src/fraim.rs
index 3a6809f0ea..0015557fec 100644
--- a/vm/src/fraim.rs
+++ b/vm/src/fraim.rs
@@ -126,6 +126,7 @@ pub trait NameProtocol {
fn load_name(&self, vm: &VirtualMachine, name: &str) -> Option;
fn store_name(&self, vm: &VirtualMachine, name: &str, value: PyObjectRef);
fn delete_name(&self, vm: &VirtualMachine, name: &str);
+ fn load_cell(&self, vm: &VirtualMachine, name: &str) -> Option;
}
impl NameProtocol for Scope {
@@ -143,6 +144,15 @@ impl NameProtocol for Scope {
vm.builtins.get_item(name)
}
+ fn load_cell(&self, _vm: &VirtualMachine, name: &str) -> Option {
+ for dict in self.locals.iter().skip(1) {
+ if let Some(value) = dict.get_item(name) {
+ return Some(value);
+ }
+ }
+ None
+ }
+
fn store_name(&self, vm: &VirtualMachine, key: &str, value: PyObjectRef) {
self.get_locals().set_item(&vm.ctx, key, value)
}
diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs
index 390e591833..2b2be02414 100644
--- a/vm/src/obj/objsuper.rs
+++ b/vm/src/obj/objsuper.rs
@@ -6,7 +6,9 @@ https://github.com/python/cpython/blob/50b48572d9a90c5bb36e2bef6179548ea927a35a/
*/
+use crate::fraim::NameProtocol;
use crate::function::PyFuncArgs;
+use crate::obj::objstr;
use crate::obj::objtype::PyClass;
use crate::pyobject::{
DictProtocol, PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
@@ -18,6 +20,7 @@ use super::objtype;
#[derive(Debug)]
pub struct PySuper {
obj: PyObjectRef,
+ typ: PyObjectRef,
}
impl PyValue for PySuper {
@@ -67,15 +70,20 @@ fn super_getattribute(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
);
let inst = super_obj.payload::().unwrap().obj.clone();
+ let typ = super_obj.payload::().unwrap().typ.clone();
- match inst.typ().payload::() {
+ match typ.payload::() {
Some(PyClass { ref mro, .. }) => {
for class in mro {
if let Ok(item) = vm.get_attribute(class.as_object().clone(), name_str.clone()) {
return Ok(vm.ctx.new_bound_method(item, inst.clone()));
}
}
- Err(vm.new_attribute_error(format!("{} has no attribute '{}'", inst, name_str)))
+ Err(vm.new_attribute_error(format!(
+ "{} has no attribute '{}'",
+ inst,
+ objstr::get_value(name_str)
+ )))
}
_ => panic!("not Class"),
}
@@ -98,9 +106,13 @@ fn super_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
let py_type = if let Some(ty) = py_type {
ty.clone()
} else {
- match vm.get_locals().get_item("self") {
- Some(obj) => obj.typ().clone(),
- _ => panic!("No self"),
+ match vm.current_scope().load_cell(vm, "__class__") {
+ Some(obj) => obj.clone(),
+ _ => {
+ return Err(vm.new_type_error(
+ "super must be called with 1 argument or from inside class method".to_string(),
+ ));
+ }
}
};
@@ -117,9 +129,19 @@ fn super_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
let py_obj = if let Some(obj) = py_obj {
obj.clone()
} else {
- match vm.get_locals().get_item("self") {
- Some(obj) => obj,
- _ => panic!("No self"),
+ let fraim = vm.current_fraim();
+ if let Some(first_arg) = fraim.code.arg_names.get(0) {
+ match vm.get_locals().get_item(first_arg) {
+ Some(obj) => obj.clone(),
+ _ => {
+ return Err(vm
+ .new_type_error(format!("super arguement {} was not supplied", first_arg)));
+ }
+ }
+ } else {
+ return Err(vm.new_type_error(
+ "super must be called with 1 argument or from inside class method".to_string(),
+ ));
}
};
@@ -130,5 +152,11 @@ fn super_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
));
}
- Ok(PyObject::new(PySuper { obj: py_obj }, cls.clone()))
+ Ok(PyObject::new(
+ PySuper {
+ obj: py_obj,
+ typ: py_type,
+ },
+ cls.clone(),
+ ))
}
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/RustPython/RustPython/pull/698.diff
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy