Skip to content

Commit 008093c

Browse files
committed
Fix int type casting error with negative base value
Change base type from u32 to i32 Fixed: #1405
1 parent 00a0e45 commit 008093c

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

tests/snippets/ints.py

+3
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@
167167
with assert_raises(ValueError):
168168
int(' 1 ', base=37)
169169

170+
with assert_raises(ValueError):
171+
int(' 1 ', base=-1)
172+
170173
with assert_raises(TypeError):
171174
int(base=2)
172175

vm/src/obj/objint.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ struct IntOptions {
704704
#[pyarg(positional_only, optional = true)]
705705
val_options: OptionalArg<PyObjectRef>,
706706
#[pyarg(positional_or_keyword, optional = true)]
707-
base: OptionalArg<u32>,
707+
base: OptionalArg<i32>,
708708
}
709709

710710
impl IntOptions {
@@ -736,7 +736,7 @@ fn int_new(cls: PyClassRef, options: IntOptions, vm: &VirtualMachine) -> PyResul
736736
}
737737

738738
// Casting function:
739-
pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult<BigInt> {
739+
pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: i32) -> PyResult<BigInt> {
740740
if base != 0 && (base < 2 || base > 36) {
741741
return Err(vm.new_value_error("int() base must be >= 2 and <= 36, or 0".to_string()));
742742
}
@@ -772,7 +772,7 @@ pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult<Big
772772
})
773773
}
774774

775-
fn str_to_int(vm: &VirtualMachine, literal: &str, mut base: u32) -> PyResult<BigInt> {
775+
fn str_to_int(vm: &VirtualMachine, literal: &str, mut base: i32) -> PyResult<BigInt> {
776776
let mut buf = validate_literal(vm, literal, base)?;
777777
let is_signed = buf.starts_with('+') || buf.starts_with('-');
778778
let radix_range = if is_signed { 1..3 } else { 0..2 };
@@ -800,10 +800,10 @@ fn str_to_int(vm: &VirtualMachine, literal: &str, mut base: u32) -> PyResult<Big
800800
base = 10;
801801
}
802802

803-
BigInt::from_str_radix(&buf, base).map_err(|_err| invalid_literal(vm, literal, base))
803+
BigInt::from_str_radix(&buf, base as u32).map_err(|_err| invalid_literal(vm, literal, base))
804804
}
805805

806-
fn validate_literal(vm: &VirtualMachine, literal: &str, base: u32) -> PyResult<String> {
806+
fn validate_literal(vm: &VirtualMachine, literal: &str, base: i32) -> PyResult<String> {
807807
if literal.starts_with('_') || literal.ends_with('_') {
808808
return Err(invalid_literal(vm, literal, base));
809809
}
@@ -826,7 +826,7 @@ fn validate_literal(vm: &VirtualMachine, literal: &str, base: u32) -> PyResult<S
826826
Ok(buf)
827827
}
828828

829-
fn detect_base(literal: &str) -> Option<u32> {
829+
fn detect_base(literal: &str) -> Option<i32> {
830830
match literal {
831831
"0x" | "0X" => Some(16),
832832
"0o" | "0O" => Some(8),
@@ -835,7 +835,7 @@ fn detect_base(literal: &str) -> Option<u32> {
835835
}
836836
}
837837

838-
fn invalid_literal(vm: &VirtualMachine, literal: &str, base: u32) -> PyObjectRef {
838+
fn invalid_literal(vm: &VirtualMachine, literal: &str, base: i32) -> PyObjectRef {
839839
vm.new_value_error(format!(
840840
"invalid literal for int() with base {}: '{}'",
841841
base, literal

0 commit comments

Comments
 (0)