diff --git a/vm/src/import.rs b/vm/src/import.rs index 314a5c28f..b81fe0c0c 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -15,9 +15,9 @@ use super::vm::VirtualMachine; fn import_module(vm: &mut VirtualMachine, module: &String) -> PyResult { // First, see if we already loaded the module: - let sys_modules = vm.sys_module.get_item(&"modules".to_string()); - if sys_modules.contains_key(module) { - return Ok(sys_modules.get_item(module)); + let sys_modules = vm.sys_module.get_item("modules").unwrap(); + if let Some(module) = sys_modules.get_item(module) { + return Ok(module); } // Time to search for module in any place: @@ -50,7 +50,7 @@ pub fn import(vm: &mut VirtualMachine, module: &String, symbol: &Option) // If we're importing a symbol, look it up and use it, otherwise construct a module and return // that let obj = match symbol { - Some(symbol) => scope.get_item(symbol), + Some(symbol) => scope.get_item(symbol).unwrap(), None => PyObject::new( PyObjectKind::Module { name: module.clone(), diff --git a/vm/src/objfunction.rs b/vm/src/objfunction.rs index b8d2e7561..6b99b13d3 100644 --- a/vm/src/objfunction.rs +++ b/vm/src/objfunction.rs @@ -66,6 +66,8 @@ pub fn create_member_descriptor_type(type_type: PyObjectRef, object: PyObjectRef } fn member_get(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult { - let function = args.shift().get_attr(&String::from("function")); - vm.invoke(function, args) + match args.shift().get_attr("function") { + Some(function) => vm.invoke(function, args), + None => Err(vm.new_exception(String::from("Attribute Error"))), + } } diff --git a/vm/src/objtype.rs b/vm/src/objtype.rs index a3d56202f..d919042ff 100644 --- a/vm/src/objtype.rs +++ b/vm/src/objtype.rs @@ -63,12 +63,11 @@ pub fn type_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { pub fn type_call(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult { debug!("type_call: {:?}", args); let typ = args.shift(); - let new = typ.get_attr(&String::from("__new__")); + let new = typ.get_attr("__new__").unwrap(); let obj = vm.invoke(new, args.insert(typ.clone()))?; - if obj.typ().has_attr(&String::from("__init__")) { - let init = obj.typ().get_attr(&String::from("__init__")); - vm.invoke(init, args.insert(obj.clone()))?; + if let Some(init) = obj.typ().get_attr("__init__") { + let _ = vm.invoke(init, args.insert(obj.clone())).unwrap(); } Ok(obj) } @@ -76,12 +75,11 @@ pub fn type_call(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult { pub fn get_attribute(vm: &mut VirtualMachine, obj: PyObjectRef, name: &String) -> PyResult { let cls = obj.typ(); trace!("get_attribute: {:?}, {:?}, {:?}", cls, obj, name); - if cls.has_attr(name) { - let attr = cls.get_attr(name); + if let Some(attr) = cls.get_attr(name) { let attr_class = attr.typ(); - if attr_class.has_attr(&String::from("__get__")) { + if let Some(descriptor) = attr_class.get_attr("__get__") { return vm.invoke( - attr_class.get_attr(&String::from("__get__")), + descriptor, PyFuncArgs { args: vec![attr, obj, cls], }, @@ -89,10 +87,10 @@ pub fn get_attribute(vm: &mut VirtualMachine, obj: PyObjectRef, name: &String) - } } - if obj.has_attr(name) { - Ok(obj.get_attr(name)) - } else if cls.has_attr(name) { - Ok(cls.get_attr(name)) + if let Some(obj_attr) = obj.get_attr(name) { + Ok(obj_attr) + } else if let Some(cls_attr) = cls.get_attr(name) { + Ok(cls_attr) } else { Err(vm.new_exception(format!( "AttributeError: {:?} object has no attribute {}", diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index 3a2b5792c..8dbe398b1 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -272,25 +272,20 @@ impl ParentProtocol for PyObjectRef { } pub trait AttributeProtocol { - fn get_attr(&self, attr_name: &String) -> PyObjectRef; + fn get_attr(&self, attr_name: &str) -> Option; fn set_attr(&self, attr_name: &str, value: PyObjectRef); - fn has_attr(&self, attr_name: &String) -> bool; + fn has_attr(&self, attr_name: &str) -> bool; } -fn class_get_item(class: &PyObjectRef, attr_name: &String) -> Option { +fn class_get_item(class: &PyObjectRef, attr_name: &str) -> Option { let class = class.borrow(); match class.kind { - PyObjectKind::Class { ref dict, .. } => { - if dict.contains_key(attr_name) { - return Some(dict.get_item(attr_name)); - } - None - } + PyObjectKind::Class { ref dict, .. } => dict.get_item(attr_name), _ => panic!("Only classes should be in MRO!"), } } -fn class_has_item(class: &PyObjectRef, attr_name: &String) -> bool { +fn class_has_item(class: &PyObjectRef, attr_name: &str) -> bool { let class = class.borrow(); match class.kind { PyObjectKind::Class { ref dict, .. } => dict.contains_key(attr_name), @@ -299,27 +294,27 @@ fn class_has_item(class: &PyObjectRef, attr_name: &String) -> bool { } impl AttributeProtocol for PyObjectRef { - fn get_attr(&self, attr_name: &String) -> PyObjectRef { + fn get_attr(&self, attr_name: &str) -> Option { let obj = self.borrow(); match obj.kind { PyObjectKind::Module { ref dict, .. } => dict.get_item(attr_name), PyObjectKind::Class { ref mro, .. } => { if let Some(item) = class_get_item(self, attr_name) { - return item; + return Some(item); } for ref class in mro { if let Some(item) = class_get_item(class, attr_name) { - return item; + return Some(item); } } - panic!("MRO search failed: {:?} {}", obj, attr_name); + None } PyObjectKind::Instance { ref dict } => dict.get_item(attr_name), ref kind => unimplemented!("load_attr unimplemented for: {:?}", kind), } } - fn has_attr(&self, attr_name: &String) -> bool { + fn has_attr(&self, attr_name: &str) -> bool { let obj = self.borrow(); match obj.kind { PyObjectKind::Module { name: _, ref dict } => dict.contains_key(attr_name), @@ -334,25 +329,25 @@ impl AttributeProtocol for PyObjectRef { fn set_attr(&self, attr_name: &str, value: PyObjectRef) { match self.borrow().kind { - PyObjectKind::Instance { ref dict } => dict.set_item(&String::from(attr_name), value), + PyObjectKind::Instance { ref dict } => dict.set_item(attr_name, value), PyObjectKind::Class { name: _, ref dict, mro: _, - } => dict.set_item(&String::from(attr_name), value), + } => dict.set_item(attr_name, value), ref kind => unimplemented!("set_attr unimplemented for: {:?}", kind), }; } } pub trait DictProtocol { - fn contains_key(&self, k: &String) -> bool; - fn get_item(&self, k: &String) -> PyObjectRef; - fn set_item(&self, k: &String, v: PyObjectRef); + fn contains_key(&self, k: &str) -> bool; + fn get_item(&self, k: &str) -> Option; + fn set_item(&self, k: &str, v: PyObjectRef); } impl DictProtocol for PyObjectRef { - fn contains_key(&self, k: &String) -> bool { + fn contains_key(&self, k: &str) -> bool { match self.borrow().kind { PyObjectKind::Dict { ref elements } => elements.contains_key(k), PyObjectKind::Module { name: _, ref dict } => dict.contains_key(k), @@ -361,16 +356,19 @@ impl DictProtocol for PyObjectRef { } } - fn get_item(&self, k: &String) -> PyObjectRef { + fn get_item(&self, k: &str) -> Option { match self.borrow().kind { - PyObjectKind::Dict { ref elements } => elements[k].clone(), + PyObjectKind::Dict { ref elements } => match elements.get(k) { + Some(v) => Some(v.clone()), + None => None, + }, PyObjectKind::Module { name: _, ref dict } => dict.get_item(k), PyObjectKind::Scope { ref scope } => scope.locals.get_item(k), _ => panic!("TODO"), } } - fn set_item(&self, k: &String, v: PyObjectRef) { + fn set_item(&self, k: &str, v: PyObjectRef) { match self.borrow_mut().kind { PyObjectKind::Dict { elements: ref mut el, diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 2f7db0648..c15643289 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -197,7 +197,7 @@ impl VirtualMachine { let mut scope = self.current_frame().locals.clone(); loop { if scope.contains_key(name) { - let obj = scope.get_item(name); + let obj = scope.get_item(name).unwrap(); self.push_value(obj); break None; } else if scope.has_parent() {