Skip to content

Commit 3bebc19

Browse files
committed
PyList: remove get_parked_item, use macros for speed on !abi3
1 parent 4d2c173 commit 3bebc19

File tree

3 files changed

+33
-52
lines changed

3 files changed

+33
-52
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6868
- Remove `__doc__` from module's `__all__`. [#1509](https://github.com/PyO3/pyo3/pull/1509)
6969
- Remove `PYO3_CROSS_INCLUDE_DIR` environment variable and the associated C header parsing functionality. [#1521](https://github.com/PyO3/pyo3/pull/1521)
7070
- Remove `raw_pycfunction!` macro. [#1619](https://github.com/PyO3/pyo3/pull/1619)
71+
- Remove `PyList::get_parked_item`. [#1664](https://github.com/PyO3/pyo3/pull/1664)
7172

7273
### Fixed
7374
- Remove FFI definition `PyCFunction_ClearFreeList` for Python 3.9 and later. [#1425](https://github.com/PyO3/pyo3/pull/1425)

src/types/dict.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl PyDict {
5151

5252
/// Returns a new dictionary that contains the same key-value pairs as self.
5353
///
54-
/// This is equivalent to the Python expression `dict(self)`.
54+
/// This is equivalent to the Python expression `self.copy()`.
5555
pub fn copy(&self) -> PyResult<&PyDict> {
5656
unsafe {
5757
self.py()

src/types/list.rs

+31-51
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,31 @@ pub struct PyList(PyAny);
1515

1616
pyobject_native_type_core!(PyList, ffi::PyList_Type, #checkfunction=ffi::PyList_Check);
1717

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+
1834
impl PyList {
1935
/// Constructs a new list with the given elements.
2036
pub fn new<T, U>(py: Python<'_>, elements: impl IntoIterator<Item = T, IntoIter = U>) -> &PyList
2137
where
2238
T: ToPyObject,
2339
U: ExactSizeIterator<Item = T>,
2440
{
25-
let elements_iter = elements.into_iter();
26-
let len = elements_iter.len();
2741
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)))
3443
}
3544
}
3645

@@ -41,8 +50,15 @@ impl PyList {
4150

4251
/// Returns the length of the list.
4352
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+
}
4662
}
4763

4864
/// Checks if the list is empty.
@@ -56,6 +72,9 @@ impl PyList {
5672
pub fn get_item(&self, index: isize) -> &PyAny {
5773
assert!((index.abs() as usize) < self.len());
5874
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)]
5978
let ptr = ffi::PyList_GetItem(self.as_ptr(), index as Py_ssize_t);
6079

6180
// PyList_GetItem return borrowed ptr; must make owned for safety (see #890).
@@ -64,18 +83,6 @@ impl PyList {
6483
}
6584
}
6685

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-
7986
/// Sets the item at the specified index.
8087
///
8188
/// Panics if the index is out of range.
@@ -167,14 +174,7 @@ where
167174
T: ToPyObject,
168175
{
169176
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))) }
178178
}
179179
}
180180

@@ -192,14 +192,7 @@ where
192192
T: IntoPy<PyObject>,
193193
{
194194
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))) }
203196
}
204197
}
205198

@@ -244,19 +237,6 @@ mod test {
244237
assert_eq!(7, list.get_item(3).extract::<i32>().unwrap());
245238
}
246239

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-
260240
#[test]
261241
fn test_set_item() {
262242
let gil = Python::acquire_gil();

0 commit comments

Comments
 (0)