@@ -13,7 +13,7 @@ mod array {
13
13
use crate :: vm:: {
14
14
builtins:: {
15
15
IntoPyFloat , PyByteArray , PyBytes , PyBytesRef , PyDictRef , PyFloat , PyInt , PyIntRef ,
16
- PyList , PyListRef , PySliceRef , PyStr , PyStrRef , PyTupleRef , PyTypeRef ,
16
+ PyList , PyListRef , PySliceRef , PyStr , PyStrRef , PyTypeRef ,
17
17
} ,
18
18
class_or_notimplemented,
19
19
function:: { ArgBytesLike , ArgIterable , OptionalArg } ,
@@ -561,12 +561,8 @@ mod array {
561
561
fn byteswap ( self ) -> Self {
562
562
Self ( self . 0 . swap_bytes ( ) )
563
563
}
564
- fn to_object ( self , vm : & VirtualMachine ) -> PyObjectRef {
565
- vm. ctx . new_str (
566
- char:: from_u32 ( self . 0 as u32 )
567
- . unwrap_or_default ( )
568
- . to_string ( ) ,
569
- )
564
+ fn to_object ( self , _vm : & VirtualMachine ) -> PyObjectRef {
565
+ unreachable ! ( )
570
566
}
571
567
}
572
568
@@ -757,6 +753,38 @@ mod array {
757
753
}
758
754
}
759
755
756
+ fn _wchar_bytes_to_string (
757
+ bytes : & [ u8 ] ,
758
+ item_size : usize ,
759
+ vm : & VirtualMachine ,
760
+ ) -> PyResult < String > {
761
+ if item_size == 2 {
762
+ // safe because every configuration of bytes for the types we support are valid
763
+ let utf16 = unsafe {
764
+ std:: slice:: from_raw_parts (
765
+ bytes. as_ptr ( ) as * const u16 ,
766
+ bytes. len ( ) / std:: mem:: size_of :: < u16 > ( ) ,
767
+ )
768
+ } ;
769
+ Ok ( String :: from_utf16_lossy ( utf16) )
770
+ } else {
771
+ // safe because every configuration of bytes for the types we support are valid
772
+ let chars = unsafe {
773
+ std:: slice:: from_raw_parts (
774
+ bytes. as_ptr ( ) as * const u32 ,
775
+ bytes. len ( ) / std:: mem:: size_of :: < u32 > ( ) ,
776
+ )
777
+ } ;
778
+ chars
779
+ . iter ( )
780
+ . map ( |& ch| {
781
+ // cpython issue 17223
782
+ u32_to_char ( ch) . map_err ( |msg| vm. new_value_error ( msg) )
783
+ } )
784
+ . try_collect ( )
785
+ }
786
+ }
787
+
760
788
fn _unicode_to_wchar_bytes ( utf8 : & str , item_size : usize ) -> Vec < u8 > {
761
789
if item_size == 2 {
762
790
utf8. encode_utf16 ( )
@@ -797,31 +825,7 @@ mod array {
797
825
) ) ;
798
826
}
799
827
let bytes = array. get_bytes ( ) ;
800
- if self . itemsize ( ) == 2 {
801
- // safe because every configuration of bytes for the types we support are valid
802
- let utf16 = unsafe {
803
- std:: slice:: from_raw_parts (
804
- bytes. as_ptr ( ) as * const u16 ,
805
- bytes. len ( ) / std:: mem:: size_of :: < u16 > ( ) ,
806
- )
807
- } ;
808
- Ok ( String :: from_utf16_lossy ( utf16) )
809
- } else {
810
- // safe because every configuration of bytes for the types we support are valid
811
- let chars = unsafe {
812
- std:: slice:: from_raw_parts (
813
- bytes. as_ptr ( ) as * const u32 ,
814
- bytes. len ( ) / std:: mem:: size_of :: < u32 > ( ) ,
815
- )
816
- } ;
817
- chars
818
- . iter ( )
819
- . map ( |& ch| {
820
- // cpython issue 17223
821
- u32_to_char ( ch) . map_err ( |msg| vm. new_value_error ( msg) )
822
- } )
823
- . try_collect ( )
824
- }
828
+ Self :: _wchar_bytes_to_string ( bytes, self . itemsize ( ) , vm)
825
829
}
826
830
827
831
fn _from_bytes ( & self , b : & [ u8 ] , itemsize : usize , vm : & VirtualMachine ) -> PyResult < ( ) > {
@@ -1111,21 +1115,21 @@ mod array {
1111
1115
zelf : PyRef < Self > ,
1112
1116
proto : usize ,
1113
1117
vm : & VirtualMachine ,
1114
- ) -> PyResult < ( PyObjectRef , PyTupleRef , Option < PyDictRef > ) > {
1118
+ ) -> PyResult < ( PyObjectRef , PyObjectRef , Option < PyDictRef > ) > {
1115
1119
if proto < 3 {
1116
- return Ok ( Self :: reduce ( zelf, vm) ) ;
1120
+ return Self :: reduce ( zelf, vm) ;
1117
1121
}
1118
1122
let array = zelf. read ( ) ;
1119
1123
let cls = zelf. as_object ( ) . clone_class ( ) . into_object ( ) ;
1120
- let typecode = vm. ctx . new_str ( array. typecode_str ( ) ) ;
1124
+ let typecode = vm. ctx . new_utf8_str ( array. typecode_str ( ) ) ;
1121
1125
let bytes = vm. ctx . new_bytes ( array. get_bytes ( ) . to_vec ( ) ) ;
1122
1126
let code = MachineFormatCode :: from_typecode ( array. typecode ( ) ) . unwrap ( ) ;
1123
1127
let code = PyInt :: from ( u8:: from ( code) ) . into_object ( vm) ;
1124
1128
let module = vm. import ( "array" , None , 0 ) ?;
1125
1129
let func = vm. get_attribute ( module, "_array_reconstructor" ) ?;
1126
1130
Ok ( (
1127
1131
func,
1128
- PyTupleRef :: with_elements ( vec ! [ cls, typecode, code, bytes] , & vm . ctx ) ,
1132
+ vm . ctx . new_tuple ( vec ! [ cls, typecode, code, bytes] ) ,
1129
1133
zelf. as_object ( ) . dict ( ) ,
1130
1134
) )
1131
1135
}
@@ -1134,16 +1138,22 @@ mod array {
1134
1138
fn reduce (
1135
1139
zelf : PyRef < Self > ,
1136
1140
vm : & VirtualMachine ,
1137
- ) -> ( PyObjectRef , PyTupleRef , Option < PyDictRef > ) {
1141
+ ) -> PyResult < ( PyObjectRef , PyObjectRef , Option < PyDictRef > ) > {
1138
1142
let array = zelf. read ( ) ;
1139
1143
let cls = zelf. as_object ( ) . clone_class ( ) . into_object ( ) ;
1140
- let typecode = vm. ctx . new_str ( array. typecode_str ( ) ) ;
1141
- let values = vm. ctx . new_list ( array. get_objects ( vm) ) ;
1142
- (
1144
+ let typecode = vm. ctx . new_utf8_str ( array. typecode_str ( ) ) ;
1145
+ let values = if array. typecode ( ) == 'u' {
1146
+ let s = Self :: _wchar_bytes_to_string ( array. get_bytes ( ) , array. itemsize ( ) , vm) ?;
1147
+ s. chars ( ) . map ( |x| x. into_pyobject ( vm) ) . collect ( )
1148
+ } else {
1149
+ array. get_objects ( vm)
1150
+ } ;
1151
+ let values = vm. ctx . new_list ( values) ;
1152
+ Ok ( (
1143
1153
cls,
1144
- PyTupleRef :: with_elements ( vec ! [ typecode, values] , & vm . ctx ) ,
1154
+ vm . ctx . new_tuple ( vec ! [ typecode, values] ) ,
1145
1155
zelf. as_object ( ) . dict ( ) ,
1146
- )
1156
+ ) )
1147
1157
}
1148
1158
}
1149
1159
0 commit comments