@@ -6,7 +6,7 @@ use num_integer::Integer;
6
6
use num_traits:: { Num , One , Pow , Signed , ToPrimitive , Zero } ;
7
7
8
8
use crate :: format:: FormatSpec ;
9
- use crate :: function:: { KwArgs , OptionalArg , PyFuncArgs } ;
9
+ use crate :: function:: { OptionalArg , PyFuncArgs } ;
10
10
use crate :: obj:: objtype:: PyClassRef ;
11
11
use crate :: pyhash;
12
12
use crate :: pyobject:: {
@@ -15,6 +15,7 @@ use crate::pyobject::{
15
15
} ;
16
16
use crate :: vm:: VirtualMachine ;
17
17
18
+ use super :: objbool:: IntoPyBool ;
18
19
use super :: objbyteinner:: PyByteInner ;
19
20
use super :: objbytes:: PyBytes ;
20
21
use super :: objint;
@@ -578,29 +579,21 @@ impl PyInt {
578
579
579
580
#[ pymethod]
580
581
#[ allow( clippy:: match_bool) ]
581
- fn from_bytes (
582
- bytes : PyByteInner ,
583
- byteorder : PyStringRef ,
584
- kwargs : KwArgs ,
585
- vm : & VirtualMachine ,
586
- ) -> PyResult < BigInt > {
587
- let mut signed = false ;
588
- for ( key, value) in kwargs. into_iter ( ) {
589
- if key == "signed" {
590
- signed = match_class ! ( match value {
591
- b @ PyInt => !b. as_bigint( ) . is_zero( ) ,
592
- _ => false ,
593
- } ) ;
594
- }
595
- }
596
- let x = match byteorder. as_str ( ) {
582
+ fn from_bytes ( args : IntFromByteArgs , vm : & VirtualMachine ) -> PyResult < BigInt > {
583
+ let signed = if let OptionalArg :: Present ( signed) = args. signed {
584
+ signed. to_bool ( )
585
+ } else {
586
+ false
587
+ } ;
588
+
589
+ let x = match args. byteorder . as_str ( ) {
597
590
"big" => match signed {
598
- true => BigInt :: from_signed_bytes_be ( & bytes. elements ) ,
599
- false => BigInt :: from_bytes_be ( Sign :: Plus , & bytes. elements ) ,
591
+ true => BigInt :: from_signed_bytes_be ( & args . bytes . elements ) ,
592
+ false => BigInt :: from_bytes_be ( Sign :: Plus , & args . bytes . elements ) ,
600
593
} ,
601
594
"little" => match signed {
602
- true => BigInt :: from_signed_bytes_le ( & bytes. elements ) ,
603
- false => BigInt :: from_bytes_le ( Sign :: Plus , & bytes. elements ) ,
595
+ true => BigInt :: from_signed_bytes_le ( & args . bytes . elements ) ,
596
+ false => BigInt :: from_bytes_le ( Sign :: Plus , & args . bytes . elements ) ,
604
597
} ,
605
598
_ => {
606
599
return Err (
@@ -610,36 +603,30 @@ impl PyInt {
610
603
} ;
611
604
Ok ( x)
612
605
}
606
+
613
607
#[ pymethod]
614
608
#[ allow( clippy:: match_bool) ]
615
- fn to_bytes (
616
- & self ,
617
- length : PyIntRef ,
618
- byteorder : PyStringRef ,
619
- kwargs : KwArgs ,
620
- vm : & VirtualMachine ,
621
- ) -> PyResult < PyBytes > {
622
- let mut signed = false ;
609
+ fn to_bytes ( & self , args : IntToByteArgs , vm : & VirtualMachine ) -> PyResult < PyBytes > {
610
+ let signed = if let OptionalArg :: Present ( signed) = args. signed {
611
+ signed. to_bool ( )
612
+ } else {
613
+ false
614
+ } ;
615
+
623
616
let value = self . as_bigint ( ) ;
624
- for ( key, value) in kwargs. into_iter ( ) {
625
- if key == "signed" {
626
- signed = match_class ! ( match value {
627
- b @ PyInt => !b. as_bigint( ) . is_zero( ) ,
628
- _ => false ,
629
- } ) ;
630
- }
631
- }
632
617
if value. sign ( ) == Sign :: Minus && !signed {
633
618
return Err ( vm. new_overflow_error ( "can't convert negative int to unsigned" . to_string ( ) ) ) ;
634
619
}
635
- let byte_len ;
636
- if let Some ( temp ) = length. as_bigint ( ) . to_usize ( ) {
637
- byte_len = temp ;
620
+
621
+ let byte_len = if let Some ( byte_len ) = args . length . as_bigint ( ) . to_usize ( ) {
622
+ byte_len
638
623
} else {
639
- return Err ( vm. new_value_error ( "length parameter is illegal" . to_string ( ) ) ) ;
640
- }
624
+ return Err (
625
+ vm. new_overflow_error ( "Python int too large to convert to C ssize_t" . to_string ( ) )
626
+ ) ;
627
+ } ;
641
628
642
- let mut origin_bytes = match byteorder. as_str ( ) {
629
+ let mut origin_bytes = match args . byteorder . as_str ( ) {
643
630
"big" => match signed {
644
631
true => value. to_signed_bytes_be ( ) ,
645
632
false => value. to_bytes_be ( ) . 1 ,
@@ -654,17 +641,19 @@ impl PyInt {
654
641
) ;
655
642
}
656
643
} ;
644
+
657
645
let origin_len = origin_bytes. len ( ) ;
658
646
if origin_len > byte_len {
659
- return Err ( vm. new_value_error ( "int too big to convert" . to_string ( ) ) ) ;
647
+ return Err ( vm. new_overflow_error ( "int too big to convert" . to_string ( ) ) ) ;
660
648
}
661
649
662
650
let mut append_bytes = match value. sign ( ) {
663
651
Sign :: Minus => vec ! [ 255u8 ; byte_len - origin_len] ,
664
652
_ => vec ! [ 0u8 ; byte_len - origin_len] ,
665
653
} ;
654
+
666
655
let mut bytes = vec ! [ ] ;
667
- match byteorder. as_str ( ) {
656
+ match args . byteorder . as_str ( ) {
668
657
"big" => {
669
658
bytes = append_bytes;
670
659
bytes. append ( & mut origin_bytes) ;
@@ -675,7 +664,6 @@ impl PyInt {
675
664
}
676
665
_ => ( ) ,
677
666
}
678
-
679
667
Ok ( PyBytes :: new ( bytes) )
680
668
}
681
669
#[ pyproperty]
@@ -735,6 +723,26 @@ fn int_new(cls: PyClassRef, options: IntOptions, vm: &VirtualMachine) -> PyResul
735
723
PyInt :: new ( options. get_int_value ( vm) ?) . into_ref_with_type ( vm, cls)
736
724
}
737
725
726
+ #[ derive( FromArgs ) ]
727
+ struct IntFromByteArgs {
728
+ #[ pyarg( positional_or_keyword) ]
729
+ bytes : PyByteInner ,
730
+ #[ pyarg( positional_or_keyword) ]
731
+ byteorder : PyStringRef ,
732
+ #[ pyarg( keyword_only, optional = true ) ]
733
+ signed : OptionalArg < IntoPyBool > ,
734
+ }
735
+
736
+ #[ derive( FromArgs ) ]
737
+ struct IntToByteArgs {
738
+ #[ pyarg( positional_or_keyword) ]
739
+ length : PyIntRef ,
740
+ #[ pyarg( positional_or_keyword) ]
741
+ byteorder : PyStringRef ,
742
+ #[ pyarg( keyword_only, optional = true ) ]
743
+ signed : OptionalArg < IntoPyBool > ,
744
+ }
745
+
738
746
// Casting function:
739
747
pub fn to_int ( vm : & VirtualMachine , obj : & PyObjectRef , base : & BigInt ) -> PyResult < BigInt > {
740
748
let base_u32 = match base. to_u32 ( ) {
0 commit comments