@@ -69,6 +69,7 @@ impl PyList {
69
69
/// Gets the item at the specified index.
70
70
///
71
71
/// Panics if the index is out of range.
72
+ #[ deprecated = "this is a deprecated alias for get and get_unchecked" ]
72
73
pub fn get_item ( & self , index : isize ) -> & PyAny {
73
74
assert ! ( index >= 0 && index < self . len( ) as isize ) ;
74
75
unsafe {
@@ -83,6 +84,23 @@ impl PyList {
83
84
}
84
85
}
85
86
87
+ /// Gets the list item at the specified index.
88
+ pub fn get ( & self , index : usize ) -> PyResult < & PyAny > {
89
+ unsafe {
90
+ let item = ffi:: PyList_GetItem ( self . as_ptr ( ) , index as Py_ssize_t ) ;
91
+ self . py ( ) . from_borrowed_ptr_or_err ( item)
92
+ }
93
+ }
94
+
95
+ /// Gets the list item at the specified index. Undefined behavior on bad index. Use with caution.
96
+ #[ cfg( not( any( Py_LIMITED_API , PyPy ) ) ) ]
97
+ pub fn get_unchecked ( & self , index : usize ) -> & PyAny {
98
+ unsafe {
99
+ let item = ffi:: PyList_GET_ITEM ( self . as_ptr ( ) , index as Py_ssize_t ) ;
100
+ self . py ( ) . from_borrowed_ptr ( item)
101
+ }
102
+ }
103
+
86
104
/// Sets the item at the specified index.
87
105
///
88
106
/// Panics if the index is out of range.
@@ -142,16 +160,16 @@ impl PyList {
142
160
/// Used by `PyList::iter()`.
143
161
pub struct PyListIterator < ' a > {
144
162
list : & ' a PyList ,
145
- index : isize ,
163
+ index : usize ,
146
164
}
147
165
148
166
impl < ' a > Iterator for PyListIterator < ' a > {
149
167
type Item = & ' a PyAny ;
150
168
151
169
#[ inline]
152
170
fn next ( & mut self ) -> Option < & ' a PyAny > {
153
- if self . index < self . list . len ( ) as isize {
154
- let item = self . list . get_item ( self . index ) ;
171
+ if self . index < self . list . len ( ) {
172
+ let item = self . list . get ( self . index ) . expect ( "list.get failed" ) ;
155
173
self . index += 1 ;
156
174
Some ( item)
157
175
} else {
@@ -217,10 +235,10 @@ mod test {
217
235
let gil = Python :: acquire_gil ( ) ;
218
236
let py = gil. python ( ) ;
219
237
let list = PyList :: new ( py, & [ 2 , 3 , 5 , 7 ] ) ;
220
- assert_eq ! ( 2 , list. get_item ( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
221
- assert_eq ! ( 3 , list. get_item ( 1 ) . extract:: <i32 >( ) . unwrap( ) ) ;
222
- assert_eq ! ( 5 , list. get_item ( 2 ) . extract:: <i32 >( ) . unwrap( ) ) ;
223
- assert_eq ! ( 7 , list. get_item ( 3 ) . extract:: <i32 >( ) . unwrap( ) ) ;
238
+ assert_eq ! ( 2 , list. get ( 0 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
239
+ assert_eq ! ( 3 , list. get ( 1 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
240
+ assert_eq ! ( 5 , list. get ( 2 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
241
+ assert_eq ! ( 7 , list. get ( 3 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
224
242
}
225
243
226
244
#[ test]
@@ -236,19 +254,10 @@ mod test {
236
254
let gil = Python :: acquire_gil ( ) ;
237
255
let py = gil. python ( ) ;
238
256
let list = PyList :: new ( py, & [ 2 , 3 , 5 , 7 ] ) ;
239
- assert_eq ! ( 2 , list. get_item( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
240
- assert_eq ! ( 3 , list. get_item( 1 ) . extract:: <i32 >( ) . unwrap( ) ) ;
241
- assert_eq ! ( 5 , list. get_item( 2 ) . extract:: <i32 >( ) . unwrap( ) ) ;
242
- assert_eq ! ( 7 , list. get_item( 3 ) . extract:: <i32 >( ) . unwrap( ) ) ;
243
- }
244
-
245
- #[ test]
246
- #[ should_panic]
247
- fn test_get_item_invalid ( ) {
248
- let gil = Python :: acquire_gil ( ) ;
249
- let py = gil. python ( ) ;
250
- let list = PyList :: new ( py, & [ 2 , 3 , 5 , 7 ] ) ;
251
- list. get_item ( -1 ) ;
257
+ assert_eq ! ( 2 , list. get( 0 ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) ) ;
258
+ assert_eq ! ( 3 , list. get( 1 ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) ) ;
259
+ assert_eq ! ( 5 , list. get( 2 ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) ) ;
260
+ assert_eq ! ( 7 , list. get( 3 ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) ) ;
252
261
}
253
262
254
263
#[ test]
@@ -257,9 +266,9 @@ mod test {
257
266
let py = gil. python ( ) ;
258
267
let list = PyList :: new ( py, & [ 2 , 3 , 5 , 7 ] ) ;
259
268
let val = 42i32 . to_object ( py) ;
260
- assert_eq ! ( 2 , list. get_item ( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
269
+ assert_eq ! ( 2 , list. get ( 0 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
261
270
list. set_item ( 0 , val) . unwrap ( ) ;
262
- assert_eq ! ( 42 , list. get_item ( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
271
+ assert_eq ! ( 42 , list. get ( 0 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
263
272
}
264
273
265
274
#[ test]
@@ -288,11 +297,11 @@ mod test {
288
297
let list = PyList :: new ( py, & [ 2 , 3 , 5 , 7 ] ) ;
289
298
let val = 42i32 . to_object ( py) ;
290
299
assert_eq ! ( 4 , list. len( ) ) ;
291
- assert_eq ! ( 2 , list. get_item ( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
300
+ assert_eq ! ( 2 , list. get ( 0 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
292
301
list. insert ( 0 , val) . unwrap ( ) ;
293
302
assert_eq ! ( 5 , list. len( ) ) ;
294
- assert_eq ! ( 42 , list. get_item ( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
295
- assert_eq ! ( 2 , list. get_item ( 1 ) . extract:: <i32 >( ) . unwrap( ) ) ;
303
+ assert_eq ! ( 42 , list. get ( 0 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
304
+ assert_eq ! ( 2 , list. get ( 1 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
296
305
}
297
306
298
307
#[ test]
@@ -318,8 +327,8 @@ mod test {
318
327
let py = gil. python ( ) ;
319
328
let list = PyList :: new ( py, & [ 2 ] ) ;
320
329
list. append ( 3 ) . unwrap ( ) ;
321
- assert_eq ! ( 2 , list. get_item ( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
322
- assert_eq ! ( 3 , list. get_item ( 1 ) . extract:: <i32 >( ) . unwrap( ) ) ;
330
+ assert_eq ! ( 2 , list. get ( 0 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
331
+ assert_eq ! ( 3 , list. get ( 1 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
323
332
}
324
333
325
334
#[ test]
@@ -397,15 +406,15 @@ mod test {
397
406
let py = gil. python ( ) ;
398
407
let v = vec ! [ 7 , 3 , 2 , 5 ] ;
399
408
let list = PyList :: new ( py, & v) ;
400
- assert_eq ! ( 7 , list. get_item ( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
401
- assert_eq ! ( 3 , list. get_item ( 1 ) . extract:: <i32 >( ) . unwrap( ) ) ;
402
- assert_eq ! ( 2 , list. get_item ( 2 ) . extract:: <i32 >( ) . unwrap( ) ) ;
403
- assert_eq ! ( 5 , list. get_item ( 3 ) . extract:: <i32 >( ) . unwrap( ) ) ;
409
+ assert_eq ! ( 7 , list. get ( 0 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
410
+ assert_eq ! ( 3 , list. get ( 1 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
411
+ assert_eq ! ( 2 , list. get ( 2 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
412
+ assert_eq ! ( 5 , list. get ( 3 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
404
413
list. sort ( ) . unwrap ( ) ;
405
- assert_eq ! ( 2 , list. get_item ( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
406
- assert_eq ! ( 3 , list. get_item ( 1 ) . extract:: <i32 >( ) . unwrap( ) ) ;
407
- assert_eq ! ( 5 , list. get_item ( 2 ) . extract:: <i32 >( ) . unwrap( ) ) ;
408
- assert_eq ! ( 7 , list. get_item ( 3 ) . extract:: <i32 >( ) . unwrap( ) ) ;
414
+ assert_eq ! ( 2 , list. get ( 0 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
415
+ assert_eq ! ( 3 , list. get ( 1 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
416
+ assert_eq ! ( 5 , list. get ( 2 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
417
+ assert_eq ! ( 7 , list. get ( 3 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
409
418
}
410
419
411
420
#[ test]
@@ -414,15 +423,15 @@ mod test {
414
423
let py = gil. python ( ) ;
415
424
let v = vec ! [ 2 , 3 , 5 , 7 ] ;
416
425
let list = PyList :: new ( py, & v) ;
417
- assert_eq ! ( 2 , list. get_item ( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
418
- assert_eq ! ( 3 , list. get_item ( 1 ) . extract:: <i32 >( ) . unwrap( ) ) ;
419
- assert_eq ! ( 5 , list. get_item ( 2 ) . extract:: <i32 >( ) . unwrap( ) ) ;
420
- assert_eq ! ( 7 , list. get_item ( 3 ) . extract:: <i32 >( ) . unwrap( ) ) ;
426
+ assert_eq ! ( 2 , list. get ( 0 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
427
+ assert_eq ! ( 3 , list. get ( 1 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
428
+ assert_eq ! ( 5 , list. get ( 2 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
429
+ assert_eq ! ( 7 , list. get ( 3 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
421
430
list. reverse ( ) . unwrap ( ) ;
422
- assert_eq ! ( 7 , list. get_item ( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
423
- assert_eq ! ( 5 , list. get_item ( 1 ) . extract:: <i32 >( ) . unwrap( ) ) ;
424
- assert_eq ! ( 3 , list. get_item ( 2 ) . extract:: <i32 >( ) . unwrap( ) ) ;
425
- assert_eq ! ( 2 , list. get_item ( 3 ) . extract:: <i32 >( ) . unwrap( ) ) ;
431
+ assert_eq ! ( 7 , list. get ( 0 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
432
+ assert_eq ! ( 5 , list. get ( 1 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
433
+ assert_eq ! ( 3 , list. get ( 2 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
434
+ assert_eq ! ( 2 , list. get ( 3 ) . unwrap ( ) . extract:: <i32 >( ) . unwrap( ) ) ;
426
435
}
427
436
428
437
#[ test]
@@ -431,7 +440,47 @@ mod test {
431
440
let py = gil. python ( ) ;
432
441
let array: PyObject = [ 1 , 2 ] . into_py ( py) ;
433
442
let list = <PyList as PyTryFrom >:: try_from ( array. as_ref ( py) ) . unwrap ( ) ;
434
- assert_eq ! ( 1 , list. get_item( 0 ) . extract:: <i32 >( ) . unwrap( ) ) ;
435
- assert_eq ! ( 2 , list. get_item( 1 ) . extract:: <i32 >( ) . unwrap( ) ) ;
443
+ assert_eq ! ( 1 , list. get( 0 ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) ) ;
444
+ assert_eq ! ( 2 , list. get( 1 ) . unwrap( ) . extract:: <i32 >( ) . unwrap( ) ) ;
445
+ }
446
+
447
+ #[ test]
448
+ fn test_list_get_invalid_index ( ) {
449
+ let gil = Python :: acquire_gil ( ) ;
450
+ let py = gil. python ( ) ;
451
+ let list = PyList :: new ( py, & [ 2 , 3 , 5 , 7 ] ) ;
452
+ let obj = list. get ( 5 ) ;
453
+ assert ! ( obj. is_err( ) ) ;
454
+ assert_eq ! (
455
+ obj. unwrap_err( ) . to_string( ) ,
456
+ "IndexError: list index out of range"
457
+ ) ;
458
+ }
459
+
460
+ #[ test]
461
+ fn test_list_get_sanity ( ) {
462
+ let gil = Python :: acquire_gil ( ) ;
463
+ let py = gil. python ( ) ;
464
+ let list = PyList :: new ( py, & [ 2 , 3 , 5 , 7 ] ) ;
465
+ let obj = list. get ( 0 ) ;
466
+ assert_eq ! ( obj. unwrap( ) . extract:: <i32 >( ) . unwrap( ) , 2 ) ;
467
+ }
468
+
469
+ #[ test]
470
+ fn test_list_get_unchecked_sanity ( ) {
471
+ let gil = Python :: acquire_gil ( ) ;
472
+ let py = gil. python ( ) ;
473
+ let list = PyList :: new ( py, & [ 2 , 3 , 5 , 7 ] ) ;
474
+ let obj = list. get_unchecked ( 0 ) ;
475
+ assert_eq ! ( obj. extract:: <i32 >( ) . unwrap( ) , 2 ) ;
476
+ }
477
+
478
+ #[ cfg( not( any( Py_LIMITED_API , PyPy ) ) ) ]
479
+ #[ test]
480
+ fn test_list_get_unchecked_invalid_index ( ) {
481
+ let gil = Python :: acquire_gil ( ) ;
482
+ let py = gil. python ( ) ;
483
+ let list = PyList :: new ( py, & [ 2 , 3 , 5 , 7 ] ) ;
484
+ list. get_unchecked ( 5 ) ;
436
485
}
437
486
}
0 commit comments