Skip to content

Commit 5cdd0ab

Browse files
committed
Check list elements on int type
1 parent 999c625 commit 5cdd0ab

File tree

4 files changed

+46
-13
lines changed

4 files changed

+46
-13
lines changed

tests/snippets/basic_types.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@
2828

2929
a = bytes([1, 2, 3])
3030
print(a)
31+
try:
32+
bytes([object()])
33+
except TypeError:
34+
pass
3135

vm/src/obj/objbytes.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@ fn bytes_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
2323
required = [(zelf, Some(vm.ctx.bytes_type())), (arg, None)]
2424
);
2525
let val = if objtype::isinstance(arg.clone(), vm.ctx.list_type()) {
26-
objlist::get_elements(arg.clone())
27-
.into_iter()
28-
.map(|e| objint::get_value(&e) as u8)
29-
.collect()
26+
let mut data_bytes = vec![];
27+
for elem in objlist::get_elements(arg.clone()) {
28+
let v = match objint::to_int(vm, &elem) {
29+
Ok(int_ref) => int_ref,
30+
Err(err) => return Err(err),
31+
};
32+
data_bytes.push(v as u8);
33+
}
34+
data_bytes
3035
} else {
31-
return Err(vm.new_type_error("Cannot construct int".to_string()));
36+
return Err(vm.new_type_error("Cannot construct bytes".to_string()));
3237
};
3338
set_value(zelf, val);
3439
Ok(vm.get_none())

vm/src/obj/objint.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,29 @@ fn int_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
1919
args,
2020
required = [(zelf, Some(vm.ctx.int_type())), (arg, None)]
2121
);
22-
let val = if objtype::isinstance(arg.clone(), vm.ctx.int_type()) {
23-
get_value(arg)
24-
} else if objtype::isinstance(arg.clone(), vm.ctx.float_type()) {
25-
objfloat::get_value(arg) as i32
26-
} else {
27-
return Err(vm.new_type_error("Cannot construct int".to_string()));
22+
23+
// Try to cast to int:
24+
let val = match to_int(vm, arg) {
25+
Ok(val) => val,
26+
Err(err) => return Err(err),
2827
};
28+
2929
set_value(zelf, val);
3030
Ok(vm.get_none())
3131
}
3232

33+
// Casting function:
34+
pub fn to_int(vm: &mut VirtualMachine, obj: &PyObjectRef) -> Result<i32, PyObjectRef> {
35+
let val = if objtype::isinstance(obj.clone(), vm.ctx.int_type()) {
36+
get_value(obj)
37+
} else if objtype::isinstance(obj.clone(), vm.ctx.float_type()) {
38+
objfloat::get_value(obj) as i32
39+
} else {
40+
return Err(vm.new_type_error("Cannot construct int".to_string()));
41+
};
42+
Ok(val)
43+
}
44+
3345
// Retrieve inner int value:
3446
pub fn get_value(obj: &PyObjectRef) -> i32 {
3547
if let PyObjectKind::Integer { value } = &obj.borrow().kind {

vm/src/obj/objtype.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,22 @@ pub fn type_call(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
113113
debug!("type_call: {:?}", args);
114114
let typ = args.shift();
115115
let new = typ.get_attr("__new__").unwrap();
116-
let obj = vm.invoke(new, args.insert(typ.clone()))?;
116+
let obj = match vm.invoke(new, args.insert(typ.clone())) {
117+
Ok(res) => res,
118+
Err(err) => return Err(err),
119+
};
117120

118121
if let Some(init) = obj.typ().get_attr("__init__") {
119-
let _ = vm.invoke(init, args.insert(obj.clone())).unwrap();
122+
match vm.invoke(init, args.insert(obj.clone())) {
123+
Ok(res) => {
124+
// TODO: assert that return is none?
125+
if !isinstance(res, vm.get_none()) {
126+
// panic!("__init__ must return none");
127+
// return Err(vm.new_type_error("__init__ must return None".to_string()));
128+
}
129+
}
130+
Err(err) => return Err(err),
131+
}
120132
}
121133
Ok(obj)
122134
}

0 commit comments

Comments
 (0)