@@ -3,8 +3,10 @@ use crate::object::define_py_check;
33use crate :: pystate:: with_vm;
44use core:: ffi:: c_int;
55use core:: ptr:: NonNull ;
6+ use rustpython_vm:: AsObject ;
67use rustpython_vm:: PyObjectRef ;
78use rustpython_vm:: builtins:: PyList ;
9+ use rustpython_vm:: sliceable:: { SaturatedSlice , SliceableSequenceMutOp , SliceableSequenceOp } ;
810
911define_py_check ! ( fn PyList_Check , types. list_type) ;
1012define_py_check ! ( exact fn PyList_CheckExact , types. list_type) ;
@@ -110,16 +112,69 @@ pub unsafe extern "C" fn PyList_Reverse(list: *mut PyObject) -> c_int {
110112 } )
111113}
112114
115+ #[ unsafe( no_mangle) ]
116+ pub unsafe extern "C" fn PyList_AsTuple ( list : * mut PyObject ) -> * mut PyObject {
117+ with_vm ( |vm| {
118+ let list = unsafe { & * list } . try_downcast_ref :: < PyList > ( vm) ?;
119+ Ok ( vm. ctx . new_tuple ( list. borrow_vec ( ) . to_vec ( ) ) )
120+ } )
121+ }
122+
123+ #[ unsafe( no_mangle) ]
124+ pub unsafe extern "C" fn PyList_GetSlice (
125+ list : * mut PyObject ,
126+ low : isize ,
127+ high : isize ,
128+ ) -> * mut PyObject {
129+ with_vm ( |vm| {
130+ let list = unsafe { & * list } . try_downcast_ref :: < PyList > ( vm) ?;
131+ let vec = list. borrow_vec ( ) ;
132+ let sliced = vec. getitem_by_slice ( vm, SaturatedSlice :: from_parts ( low, high, 1 ) ) ?;
133+ Ok ( vm. ctx . new_list ( sliced) )
134+ } )
135+ }
136+
137+ #[ unsafe( no_mangle) ]
138+ pub unsafe extern "C" fn PyList_SetSlice (
139+ list : * mut PyObject ,
140+ low : isize ,
141+ high : isize ,
142+ itemlist : * mut PyObject ,
143+ ) -> c_int {
144+ with_vm ( |vm| {
145+ let list = unsafe { & * list } . try_downcast_ref :: < PyList > ( vm) ?;
146+ let slice = SaturatedSlice :: from_parts ( low, high, 1 ) ;
147+ let mut vec = list. borrow_vec_mut ( ) ;
148+
149+ if itemlist. is_null ( ) {
150+ vec. delitem_by_slice ( vm, slice) ?;
151+ return Ok ( ( ) ) ;
152+ }
153+
154+ let items: Vec < PyObjectRef > = unsafe { & * itemlist } . try_to_value ( vm) ?;
155+ vec. setitem_by_slice ( vm, slice, & items)
156+ } )
157+ }
158+
159+ #[ unsafe( no_mangle) ]
160+ pub unsafe extern "C" fn PyList_Sort ( list : * mut PyObject ) -> c_int {
161+ with_vm ( |vm| {
162+ let list = unsafe { & * list } . try_downcast_ref :: < PyList > ( vm) ?;
163+ vm. call_method ( list. as_object ( ) , "sort" , ( ) ) ?;
164+ Ok ( ( ) )
165+ } )
166+ }
167+
113168#[ cfg( false ) ]
114169mod tests {
115170 use pyo3:: exceptions:: PyIndexError ;
116171 use pyo3:: prelude:: * ;
117- use pyo3:: types:: PyList ;
172+ use pyo3:: types:: { PyList , PyListMethods } ;
118173
119174 #[ test]
120- fn test_create_list ( ) {
175+ fn create_list ( ) {
121176 Python :: attach ( |py| {
122- let list = PyList :: new ( py, & [ 1 , 2 , 3 ] ) . unwrap ( ) ;
177+ let list = PyList :: new ( py, [ 1 , 2 , 3 ] ) . unwrap ( ) ;
123178 assert_eq ! ( list. len( ) , 3 ) ;
124179 assert_eq ! ( list. get_item( 0 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 1 ) ;
125180 assert_eq ! ( list. get_item( 1 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 2 ) ;
@@ -129,9 +184,9 @@ mod tests {
129184 }
130185
131186 #[ test]
132- fn test_replace_item_in_list ( ) {
187+ fn replace_item_in_list ( ) {
133188 Python :: attach ( |py| {
134- let list = PyList :: new ( py, & [ 1 ] ) . unwrap ( ) ;
189+ let list = PyList :: new ( py, [ 1 ] ) . unwrap ( ) ;
135190 assert_eq ! ( list. len( ) , 1 ) ;
136191 list. set_item ( 0 , 2 ) . unwrap ( ) ;
137192 assert_eq ! ( list. len( ) , 1 ) ;
@@ -140,7 +195,7 @@ mod tests {
140195 }
141196
142197 #[ test]
143- fn test_set_item_out_of_range ( ) {
198+ fn set_item_out_of_range ( ) {
144199 Python :: attach ( |py| {
145200 let list = PyList :: empty ( py) ;
146201 assert ! (
@@ -152,7 +207,7 @@ mod tests {
152207 }
153208
154209 #[ test]
155- fn test_list_append ( ) {
210+ fn list_append ( ) {
156211 Python :: attach ( |py| {
157212 let list = PyList :: empty ( py) ;
158213 assert_eq ! ( list. len( ) , 0 ) ;
@@ -163,7 +218,7 @@ mod tests {
163218 }
164219
165220 #[ test]
166- fn test_list_insert ( ) {
221+ fn list_insert ( ) {
167222 Python :: attach ( |py| {
168223 let list = PyList :: empty ( py) ;
169224 assert_eq ! ( list. len( ) , 0 ) ;
@@ -175,12 +230,62 @@ mod tests {
175230 }
176231
177232 #[ test]
178- fn test_list_reverse ( ) {
233+ fn list_reverse ( ) {
179234 Python :: attach ( |py| {
180- let list = PyList :: new ( py, & [ 1 , 2 , 3 ] ) . unwrap ( ) ;
235+ let list = PyList :: new ( py, [ 1 , 2 , 3 ] ) . unwrap ( ) ;
181236 list. reverse ( ) . unwrap ( ) ;
182237 assert_eq ! ( list. get_item( 0 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 3 ) ;
183238 assert_eq ! ( list. get_item( 2 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 1 ) ;
184239 } )
185240 }
241+
242+ #[ test]
243+ fn list_as_tuple ( ) {
244+ Python :: attach ( |py| {
245+ let list = PyList :: new ( py, [ 1 , 2 , 3 ] ) . unwrap ( ) ;
246+ let tuple = list. to_tuple ( ) ;
247+ assert_eq ! ( tuple. len( ) , 3 ) ;
248+ assert_eq ! ( tuple. get_item( 0 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 1 ) ;
249+
250+ list. set_item ( 0 , 9 ) . unwrap ( ) ;
251+ assert_eq ! ( tuple. get_item( 0 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 1 ) ;
252+ } )
253+ }
254+
255+ #[ test]
256+ fn list_get_slice ( ) {
257+ Python :: attach ( |py| {
258+ let list = PyList :: new ( py, [ 1 , 2 , 3 , 4 ] ) . unwrap ( ) ;
259+ let slice = list. get_slice ( 1 , 10 ) ;
260+ assert_eq ! ( slice. len( ) , 3 ) ;
261+ assert_eq ! ( slice. get_item( 0 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 2 ) ;
262+ assert_eq ! ( slice. get_item( 2 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 4 ) ;
263+ } )
264+ }
265+
266+ #[ test]
267+ fn list_set_slice ( ) {
268+ Python :: attach ( |py| {
269+ let list = PyList :: new ( py, [ 1 , 2 , 3 , 4 ] ) . unwrap ( ) ;
270+ let repl = PyList :: new ( py, [ 8 , 9 ] ) . unwrap ( ) ;
271+ list. set_slice ( 1 , 3 , repl. as_any ( ) ) . unwrap ( ) ;
272+
273+ assert_eq ! ( list. len( ) , 4 ) ;
274+ assert_eq ! ( list. get_item( 0 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 1 ) ;
275+ assert_eq ! ( list. get_item( 1 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 8 ) ;
276+ assert_eq ! ( list. get_item( 2 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 9 ) ;
277+ assert_eq ! ( list. get_item( 3 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 4 ) ;
278+ } )
279+ }
280+
281+ #[ test]
282+ fn list_sort ( ) {
283+ Python :: attach ( |py| {
284+ let list = PyList :: new ( py, [ 3 , 1 , 2 ] ) . unwrap ( ) ;
285+ list. sort ( ) . unwrap ( ) ;
286+ assert_eq ! ( list. get_item( 0 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 1 ) ;
287+ assert_eq ! ( list. get_item( 1 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 2 ) ;
288+ assert_eq ! ( list. get_item( 2 ) . unwrap( ) . extract:: <u32 >( ) . unwrap( ) , 3 ) ;
289+ } )
290+ }
186291}
0 commit comments