@@ -15,22 +15,31 @@ pub struct PyList(PyAny);
15
15
16
16
pyobject_native_type_core ! ( PyList , ffi:: PyList_Type , #checkfunction=ffi:: PyList_Check ) ;
17
17
18
+ #[ inline]
19
+ unsafe fn new_from_iter < T > (
20
+ elements : impl ExactSizeIterator < Item = T > ,
21
+ convert : impl Fn ( T ) -> PyObject ,
22
+ ) -> * mut ffi:: PyObject {
23
+ let ptr = ffi:: PyList_New ( elements. len ( ) as Py_ssize_t ) ;
24
+ for ( i, e) in elements. enumerate ( ) {
25
+ let obj = convert ( e) . into_ptr ( ) ;
26
+ #[ cfg( not( Py_LIMITED_API ) ) ]
27
+ ffi:: PyList_SET_ITEM ( ptr, i as Py_ssize_t , obj) ;
28
+ #[ cfg( Py_LIMITED_API ) ]
29
+ ffi:: PyList_SetItem ( ptr, i as Py_ssize_t , obj) ;
30
+ }
31
+ ptr
32
+ }
33
+
18
34
impl PyList {
19
35
/// Constructs a new list with the given elements.
20
36
pub fn new < T , U > ( py : Python < ' _ > , elements : impl IntoIterator < Item = T , IntoIter = U > ) -> & PyList
21
37
where
22
38
T : ToPyObject ,
23
39
U : ExactSizeIterator < Item = T > ,
24
40
{
25
- let elements_iter = elements. into_iter ( ) ;
26
- let len = elements_iter. len ( ) ;
27
41
unsafe {
28
- let ptr = ffi:: PyList_New ( len as Py_ssize_t ) ;
29
- for ( i, e) in elements_iter. enumerate ( ) {
30
- let obj = e. to_object ( py) . into_ptr ( ) ;
31
- ffi:: PyList_SetItem ( ptr, i as Py_ssize_t , obj) ;
32
- }
33
- py. from_owned_ptr :: < PyList > ( ptr)
42
+ py. from_owned_ptr :: < PyList > ( new_from_iter ( elements. into_iter ( ) , |e| e. to_object ( py) ) )
34
43
}
35
44
}
36
45
@@ -41,8 +50,15 @@ impl PyList {
41
50
42
51
/// Returns the length of the list.
43
52
pub fn len ( & self ) -> usize {
44
- // non-negative Py_ssize_t should always fit into Rust usize
45
- unsafe { ffi:: PyList_Size ( self . as_ptr ( ) ) as usize }
53
+ unsafe {
54
+ #[ cfg( not( Py_LIMITED_API ) ) ]
55
+ let size = ffi:: PyList_GET_SIZE ( self . as_ptr ( ) ) ;
56
+ #[ cfg( Py_LIMITED_API ) ]
57
+ let size = ffi:: PyList_Size ( self . as_ptr ( ) ) ;
58
+
59
+ // non-negative Py_ssize_t should always fit into Rust usize
60
+ size as usize
61
+ }
46
62
}
47
63
48
64
/// Checks if the list is empty.
@@ -56,6 +72,9 @@ impl PyList {
56
72
pub fn get_item ( & self , index : isize ) -> & PyAny {
57
73
assert ! ( ( index. abs( ) as usize ) < self . len( ) ) ;
58
74
unsafe {
75
+ #[ cfg( not( Py_LIMITED_API ) ) ]
76
+ let ptr = ffi:: PyList_GET_ITEM ( self . as_ptr ( ) , index as Py_ssize_t ) ;
77
+ #[ cfg( Py_LIMITED_API ) ]
59
78
let ptr = ffi:: PyList_GetItem ( self . as_ptr ( ) , index as Py_ssize_t ) ;
60
79
61
80
// PyList_GetItem return borrowed ptr; must make owned for safety (see #890).
@@ -64,18 +83,6 @@ impl PyList {
64
83
}
65
84
}
66
85
67
- /// Gets the item at the specified index.
68
- ///
69
- /// Panics if the index is out of range.
70
- pub fn get_parked_item ( & self , index : isize ) -> PyObject {
71
- unsafe {
72
- PyObject :: from_borrowed_ptr (
73
- self . py ( ) ,
74
- ffi:: PyList_GetItem ( self . as_ptr ( ) , index as Py_ssize_t ) ,
75
- )
76
- }
77
- }
78
-
79
86
/// Sets the item at the specified index.
80
87
///
81
88
/// Panics if the index is out of range.
@@ -167,14 +174,7 @@ where
167
174
T : ToPyObject ,
168
175
{
169
176
fn to_object ( & self , py : Python < ' _ > ) -> PyObject {
170
- unsafe {
171
- let ptr = ffi:: PyList_New ( self . len ( ) as Py_ssize_t ) ;
172
- for ( i, e) in self . iter ( ) . enumerate ( ) {
173
- let obj = e. to_object ( py) . into_ptr ( ) ;
174
- ffi:: PyList_SetItem ( ptr, i as Py_ssize_t , obj) ;
175
- }
176
- PyObject :: from_owned_ptr ( py, ptr)
177
- }
177
+ unsafe { PyObject :: from_owned_ptr ( py, new_from_iter ( self . iter ( ) , |e| e. to_object ( py) ) ) }
178
178
}
179
179
}
180
180
@@ -192,14 +192,7 @@ where
192
192
T : IntoPy < PyObject > ,
193
193
{
194
194
fn into_py ( self , py : Python ) -> PyObject {
195
- unsafe {
196
- let ptr = ffi:: PyList_New ( self . len ( ) as Py_ssize_t ) ;
197
- for ( i, e) in self . into_iter ( ) . enumerate ( ) {
198
- let obj = e. into_py ( py) . into_ptr ( ) ;
199
- ffi:: PyList_SetItem ( ptr, i as Py_ssize_t , obj) ;
200
- }
201
- PyObject :: from_owned_ptr ( py, ptr)
202
- }
195
+ unsafe { PyObject :: from_owned_ptr ( py, new_from_iter ( self . into_iter ( ) , |e| e. into_py ( py) ) ) }
203
196
}
204
197
}
205
198
@@ -244,19 +237,6 @@ mod test {
244
237
assert_eq ! ( 7 , list. get_item( 3 ) . extract:: <i32 >( ) . unwrap( ) ) ;
245
238
}
246
239
247
- #[ test]
248
- fn test_get_parked_item ( ) {
249
- let gil = Python :: acquire_gil ( ) ;
250
- let py = gil. python ( ) ;
251
- let v = vec ! [ 2 , 3 , 5 , 7 ] ;
252
- let ob = v. to_object ( py) ;
253
- let list = <PyList as PyTryFrom >:: try_from ( ob. as_ref ( py) ) . unwrap ( ) ;
254
- assert_eq ! ( 2 , list. get_parked_item( 0 ) . extract:: <i32 >( py) . unwrap( ) ) ;
255
- assert_eq ! ( 3 , list. get_parked_item( 1 ) . extract:: <i32 >( py) . unwrap( ) ) ;
256
- assert_eq ! ( 5 , list. get_parked_item( 2 ) . extract:: <i32 >( py) . unwrap( ) ) ;
257
- assert_eq ! ( 7 , list. get_parked_item( 3 ) . extract:: <i32 >( py) . unwrap( ) ) ;
258
- }
259
-
260
240
#[ test]
261
241
fn test_set_item ( ) {
262
242
let gil = Python :: acquire_gil ( ) ;
0 commit comments