8000 Improve int type error · rmliddle/RustPython@947c17e · GitHub
[go: up one dir, main page]

Skip to content

Commit 947c17e

Browse files
committed
Improve int type error
1 parent a9bc374 commit 947c17e

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

vm/src/obj/objbytes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn bytes_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
2424
let val = if objtype::isinstance(arg, vm.ctx.list_type()) {
2525
let mut data_bytes = vec![];
2626
for elem in objlist::get_elements(arg) {
27-
let v = match objint::to_int(vm, &elem) {
27+
let v = match objint::to_int(vm, &elem, 10) {
2828
Ok(int_ref) => int_ref,
2929
Err(err) => return Err(err),
3030
};

vm/src/obj/objint.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use super::super::pyobject::{
44
};
55
use super::super::vm::VirtualMachine;
66
use super::objfloat;
7+
use super::objstr;
78
use super::objtype;
89

910
fn int_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -17,21 +18,40 @@ fn int_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
1718
if !objtype::issubclass(cls, vm.ctx.int_type()) {
1819
return Err(vm.new_type_error(format!("{:?} is not a subtype of int", cls)));
1920
}
20-
let val = to_int(vm, &args.args[1].clone())?;
21+
22+
// TODO: extract kwargs:
23+
let base = 10;
24+
let val = to_int(vm, &args.args[1].clone(), base)?;
2125
Ok(PyObject::new(
2226
PyObjectKind::Integer { value: val },
2327
cls.clone(),
2428
))
2529
}
2630

2731
// Casting function:
28-
pub fn to_int(vm: &mut VirtualMachine, obj: &PyObjectRef) -> Result<i32, PyObjectRef> {
32+
pub fn to_int(vm: &mut VirtualMachine, obj: &PyObjectRef, base: u32) -> Result<i32, PyObjectRef> {
2933
let val = if objtype::isinstance(obj, vm.ctx.int_type()) {
3034
get_value(obj)
3135
} else if objtype::isinstance(obj, vm.ctx.float_type()) {
3236
objfloat::get_value(obj) as i32
37+
} else if objtype::isinstance(obj, vm.ctx.str_type()) {
38+
let s = objstr::get_value(obj);
39+
match i32::from_str_radix(&s, base) {
40+
Ok(v) => v,
41+
Err(err) => {
42+
trace!("Error occured during int conversion {:?}", err);
43+
return Err(vm.new_value_error(format!(
44+
"invalid literal for int() with base {}: '{}'",
45+
base, s
46+
)));
47+
}
48+
}
3349
} else {
34-
return Err(vm.new_type_error("Cannot construct int".to_string()));
50+
let type_name = objtype::get_type_name(&obj.typ());
51+
return Err(vm.new_type_error(format!(
52+
"int() argument must be a string or a number, not '{}'",
53+
type_name
54+
)));
3555
};
3656
Ok(val)
3757
}

vm/src/vm.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,15 @@ impl VirtualMachine {
7373
}
7474

7575
pub fn new_type_error(&mut self, msg: String) -> PyObjectRef {
76-
let type_error = self.context().exceptions.type_error.clone();
76+
let type_error = self.ctx.exceptions.type_error.clone();
7777
self.new_exception(type_error, msg)
7878
}
7979

80+
pub fn new_value_error(&mut self, msg: String) -> PyObjectRef {
81+
let value_error = self.ctx.exceptions.value_error.clone();
82+
self.new_exception(value_error, msg)
83+
}
84+
8085
pub fn new_scope(&mut self) -> PyObjectRef {
8186
let parent_scope = self.current_frame_mut().locals.clone();
8287
self.ctx.new_scope(Some(parent_scope))

0 commit comments

Comments
 (0)
0