From 6acb7eb006c0e8d97f62c59a62111ba79f3f92c3 Mon Sep 17 00:00:00 2001 From: Matthew Constable Date: Sun, 3 Feb 2019 15:46:13 +0000 Subject: [PATCH] Handle attempt to add non-hashable items to a set. --- vm/src/obj/objset.rs | 26 ++++++++++++++++---------- vm/src/vm.rs | 5 ----- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs index 0966366f5..ece51ee11 100644 --- a/vm/src/obj/objset.rs +++ b/vm/src/obj/objset.rs @@ -43,20 +43,26 @@ fn set_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { match mut_obj.payload { PyObjectPayload::Set { ref mut elements } => { - let hash_result: PyObjectRef = vm.call_method(item, "__hash__", vec![]).unwrap(); - let hash_object = hash_result.borrow(); - let key: BigInt; - match hash_object.payload { - PyObjectPayload::Integer { ref value } => { - let key = value.clone(); - elements.insert(key, item.clone()); - Ok(vm.get_none()) + let hash_result: PyResult = vm.call_method(item, "__hash__", vec![]); + match hash_result { + Ok(hash_object) => { + let hash = hash_object.borrow(); + let key: BigInt; + match hash.payload { + PyObjectPayload::Integer { ref value } => { + let key = value.clone(); + elements.insert(key, item.clone()); + Ok(vm.get_none()) + }, + _ => { Err(vm.new_type_error(format!("__hash__ method should return an integer"))) } + } }, - _ => { Err(vm.new_attribute_error(format!("Expected item to implment __hash__"))) } + Err(error) => Err(error), } + }, _ => { - Err(vm.new_type_error("set.add is called with no list".to_string())) + Err(vm.new_type_error("set.add is called with no item".to_string())) } } } diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 67ea19a35..2dea87aa2 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -100,11 +100,6 @@ impl VirtualMachine { self.new_exception(type_error, msg) } - pub fn new_attribute_error(&mut self, msg: String) -> PyObjectRef { - let type_error = self.ctx.exceptions.attribute_error.clone(); - self.new_exception(type_error, msg) - } - /// Create a new python ValueError object. Useful for raising errors from /// python functions implemented in rust. pub fn new_value_error(&mut self, msg: String) -> PyObjectRef {