11use crate :: PyObject ;
22use crate :: object:: define_py_check;
33use crate :: pystate:: with_vm;
4+ use core:: ffi:: c_int;
45use core:: slice;
56use rustpython_vm:: PyResult ;
67use rustpython_vm:: builtins:: PyTuple ;
78use rustpython_vm:: sliceable:: SliceableSequenceOp ;
89
9- define_py_check ! ( fn PyTuple_Check , types. int_type ) ;
10- define_py_check ! ( exact fn PyTuple_CheckExact , types. int_type ) ;
10+ define_py_check ! ( fn PyTuple_Check , types. tuple_type ) ;
11+ define_py_check ! ( exact fn PyTuple_CheckExact , types. tuple_type ) ;
1112
1213#[ unsafe( no_mangle) ]
1314pub extern "C" fn PyTuple_New ( len : isize ) -> * mut PyObject {
@@ -28,12 +29,15 @@ pub unsafe extern "C" fn PyTuple_FromArray(
2829 size : isize ,
2930) -> * mut PyObject {
3031 with_vm ( |vm| {
31- let slice = unsafe { slice:: from_raw_parts ( array, size as usize ) } ;
32+ let size = size
33+ . try_into ( )
34+ . map_err ( |_| vm. new_system_error ( "negative size passed to Tuple_FromArray" ) ) ?;
35+ let slice = unsafe { slice:: from_raw_parts ( array, size) } ;
3236 let elements = slice
3337 . iter ( )
3438 . map ( |ptr| unsafe { & * * ptr } . to_owned ( ) )
3539 . collect :: < Vec < _ > > ( ) ;
36- vm. new_tuple ( elements)
40+ Ok ( vm. new_tuple ( elements) )
3741 } )
3842}
3943
@@ -42,8 +46,10 @@ pub extern "C" fn PyTuple_SetItem(
4246 _tuple : * mut PyObject ,
4347 _pos : isize ,
4448 _value : * mut PyObject ,
45- ) -> * mut PyObject {
46- with_vm :: < PyResult , _ > ( |vm| Err ( vm. new_not_implemented_error ( "Tuple objects are immutable" ) ) )
49+ ) -> c_int {
50+ with_vm :: < PyResult < ( ) > , _ > (
51+ |vm| Err ( vm. new_not_implemented_error ( "Tuple objects are immutable" ) ) ,
52+ )
4753}
4854
4955#[ unsafe( no_mangle) ]
@@ -75,9 +81,11 @@ pub unsafe extern "C" fn PyTuple_GetSlice(
7581 high : isize ,
7682) -> * mut PyObject {
7783 with_vm ( |vm| {
78- let slice = unsafe { & * tuple }
79- . try_downcast_ref :: < PyTuple > ( vm) ?
80- . do_slice ( low as usize ..high as usize ) ;
84+ let tuple = unsafe { & * tuple } . try_downcast_ref :: < PyTuple > ( vm) ?;
85+ let len = tuple. __len__ ( ) as isize ;
86+ let low = low. clamp ( 0 , len) ;
87+ let high = high. clamp ( low, len) ;
88+ let slice = tuple. do_slice ( low as usize ..high as usize ) ;
8189 Ok ( vm. ctx . new_tuple ( slice) )
8290 } )
8391}
0 commit comments