From 5cdd0ab7b8f31f0df12f1ebf60b885c19b9cd22a Mon Sep 17 00:00:00 2001 From: Windel Bouwman Date: Sat, 1 Sep 2018 09:54:58 +0200 Subject: [PATCH] Check list elements on int type --- tests/snippets/basic_types.py | 4 ++++ vm/src/obj/objbytes.rs | 15 ++++++++++----- vm/src/obj/objint.rs | 24 ++++++++++++++++++------ vm/src/obj/objtype.rs | 16 ++++++++++++++-- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/tests/snippets/basic_types.py b/tests/snippets/basic_types.py index c878115c4..b9dc22b27 100644 --- a/tests/snippets/basic_types.py +++ b/tests/snippets/basic_types.py @@ -28,4 +28,8 @@ assert type(x - 1) is int a = bytes([1, 2, 3]) print(a) +try: + bytes([object()]) +except TypeError: + pass diff --git a/vm/src/obj/objbytes.rs b/vm/src/obj/objbytes.rs index ebaa3cbd1..9aa4722d7 100644 --- a/vm/src/obj/objbytes.rs +++ b/vm/src/obj/objbytes.rs @@ -23,12 +23,17 @@ fn bytes_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { required = [(zelf, Some(vm.ctx.bytes_type())), (arg, None)] ); let val = if objtype::isinstance(arg.clone(), vm.ctx.list_type()) { - objlist::get_elements(arg.clone()) - .into_iter() - .map(|e| objint::get_value(&e) as u8) - .collect() + let mut data_bytes = vec![]; + for elem in objlist::get_elements(arg.clone()) { + let v = match objint::to_int(vm, &elem) { + Ok(int_ref) => int_ref, + Err(err) => return Err(err), + }; + data_bytes.push(v as u8); + } + data_bytes } else { - return Err(vm.new_type_error("Cannot construct int".to_string())); + return Err(vm.new_type_error("Cannot construct bytes".to_string())); }; set_value(zelf, val); Ok(vm.get_none()) diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index 4fe985185..e68cad0b7 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -19,15 +19,27 @@ fn int_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { args, required = [(zelf, Some(vm.ctx.int_type())), (arg, None)] ); - let val = if objtype::isinstance(arg.clone(), vm.ctx.int_type()) { - get_value(arg) - } else if objtype::isinstance(arg.clone(), vm.ctx.float_type()) { - objfloat::get_value(arg) as i32 + + // Try to cast to int: + let val = match to_int(vm, arg) { + Ok(val) => val, + Err(err) => return Err(err), + }; + + set_value(zelf, val); + Ok(vm.get_none()) +} + +// Casting function: +pub fn to_int(vm: &mut VirtualMachine, obj: &PyObjectRef) -> Result { + let val = if objtype::isinstance(obj.clone(), vm.ctx.int_type()) { + get_value(obj) + } else if objtype::isinstance(obj.clone(), vm.ctx.float_type()) { + objfloat::get_value(obj) as i32 } else { return Err(vm.new_type_error("Cannot construct int".to_string())); }; - set_value(zelf, val); - Ok(vm.get_none()) + Ok(val) } // Retrieve inner int value: diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index 771a96f35..d7b99a4eb 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -113,10 +113,22 @@ pub fn type_call(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult { debug!("type_call: {:?}", args); let typ = args.shift(); let new = typ.get_attr("__new__").unwrap(); - let obj = vm.invoke(new, args.insert(typ.clone()))?; + let obj = match vm.invoke(new, args.insert(typ.clone())) { + Ok(res) => res, + Err(err) => return Err(err), + }; if let Some(init) = obj.typ().get_attr("__init__") { - let _ = vm.invoke(init, args.insert(obj.clone())).unwrap(); + match vm.invoke(init, args.insert(obj.clone())) { + Ok(res) => { + // TODO: assert that return is none? + if !isinstance(res, vm.get_none()) { + // panic!("__init__ must return none"); + // return Err(vm.new_type_error("__init__ must return None".to_string())); + } + } + Err(err) => return Err(err), + } } Ok(obj) }