@@ -704,7 +704,7 @@ struct IntOptions {
704
704
#[ pyarg( positional_only, optional = true ) ]
705
705
val_options : OptionalArg < PyObjectRef > ,
706
706
#[ pyarg( positional_or_keyword, optional = true ) ]
707
- base : OptionalArg < u32 > ,
707
+ base : OptionalArg < PyIntRef > ,
708
708
}
709
709
710
710
impl IntOptions {
@@ -720,9 +720,9 @@ impl IntOptions {
720
720
}
721
721
base
722
722
} else {
723
- 10
723
+ PyInt :: new ( 10 ) . into_ref ( vm )
724
724
} ;
725
- to_int ( vm, & val, base)
725
+ to_int ( vm, & val, base. as_bigint ( ) )
726
726
} else if let OptionalArg :: Present ( _) = self . base {
727
727
Err ( vm. new_type_error ( "int() missing string argument" . to_string ( ) ) )
728
728
} else {
@@ -736,8 +736,14 @@ fn int_new(cls: PyClassRef, options: IntOptions, vm: &VirtualMachine) -> PyResul
736
736
}
737
737
738
738
// Casting function:
739
- pub fn to_int ( vm : & VirtualMachine , obj : & PyObjectRef , base : u32 ) -> PyResult < BigInt > {
740
- if base != 0 && ( base < 2 || base > 36 ) {
739
+ pub fn to_int ( vm : & VirtualMachine , obj : & PyObjectRef , base : & BigInt ) -> PyResult < BigInt > {
740
+ let base_u32 = match base. to_u32 ( ) {
741
+ Some ( base_u32) => base_u32,
742
+ None => {
743
+ return Err ( vm. new_value_error ( "int() base must be >= 2 and <= 36, or 0" . to_string ( ) ) )
744
+ }
745
+ } ;
746
+ if base_u32 != 0 && ( base_u32 < 2 || base_u32 > 36 ) {
741
747
return Err ( vm. new_value_error ( "int() base must be >= 2 and <= 36, or 0" . to_string ( ) ) ) ;
742
748
}
743
749
@@ -772,38 +778,43 @@ pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, base: u32) -> PyResult<Big
772
778
} )
773
779
}
774
780
775
- fn str_to_int ( vm : & VirtualMachine , literal : & str , mut base : u32 ) -> PyResult < BigInt > {
781
+ fn str_to_int ( vm : & VirtualMachine , literal : & str , base : & BigInt ) -> PyResult < BigInt > {
776
782
let mut buf = validate_literal ( vm, literal, base) ?;
777
783
let is_signed = buf. starts_with ( '+' ) || buf. starts_with ( '-' ) ;
778
784
let radix_range = if is_signed { 1 ..3 } else { 0 ..2 } ;
779
785
let radix_candidate = buf. get ( radix_range. clone ( ) ) ;
780
786
787
+ let mut base_u32 = match base. to_u32 ( ) {
788
+ Some ( base_u32) => base_u32,
789
+ None => return Err ( invalid_literal ( vm, literal, base) ) ,
790
+ } ;
791
+
781
792
// try to find base
782
793
if let Some ( radix_candidate) = radix_candidate {
783
794
if let Some ( matched_radix) = detect_base ( & radix_candidate) {
784
- if base != 0 && base != matched_radix {
795
+ if base_u32 != 0 && base_u32 != matched_radix {
785
796
return Err ( invalid_literal ( vm, literal, base) ) ;
786
797
} else {
787
- base = matched_radix;
798
+ base_u32 = matched_radix;
788
799
}
789
800
790
801
buf. drain ( radix_range) ;
791
802
}
792
803
}
793
804
794
805
// base still not found, try to use default
795
- if base == 0 {
806
+ if base_u32 == 0 {
796
807
if buf. starts_with ( '0' ) {
797
808
return Err ( invalid_literal ( vm, literal, base) ) ;
798
809
}
799
810
800
- base = 10 ;
811
+ base_u32 = 10 ;
801
812
}
802
813
803
- BigInt :: from_str_radix ( & buf, base ) . map_err ( |_err| invalid_literal ( vm, literal, base) )
814
+ BigInt :: from_str_radix ( & buf, base_u32 ) . map_err ( |_err| invalid_literal ( vm, literal, base) )
804
815
}
805
816
806
- fn validate_literal ( vm : & VirtualMachine , literal : & str , base : u32 ) -> PyResult < String > {
817
+ fn validate_literal ( vm : & VirtualMachine , literal : & str , base : & BigInt ) -> PyResult < String > {
807
818
if literal. starts_with ( '_' ) || literal. ends_with ( '_' ) {
808
819
return Err ( invalid_literal ( vm, literal, base) ) ;
809
820
}
@@ -835,7 +846,7 @@ fn detect_base(literal: &str) -> Option<u32> {
835
846
}
836
847
}
837
848
838
- fn invalid_literal ( vm : & VirtualMachine , literal : & str , base : u32 ) -> PyObjectRef {
849
+ fn invalid_literal ( vm : & VirtualMachine , literal : & str , base : & BigInt ) -> PyObjectRef {
839
850
vm. new_value_error ( format ! (
840
851
"invalid literal for int() with base {}: '{}'" ,
841
852
base, literal
0 commit comments