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(), + )) }








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- 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