feature gate deprecated APIs for PyList (#4127)

This commit is contained in:
Icxolu 2024-05-01 00:00:31 +02:00 committed by GitHub
parent 82c00a2fe4
commit 2f3a33fda1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 104 additions and 94 deletions

View file

@ -75,7 +75,7 @@ Python::with_gil(|py| {
After:
```rust
```rust,ignore
# use pyo3::prelude::*;
# use pyo3::types::{PyInt, PyList};
# fn main() -> PyResult<()> {
@ -1089,7 +1089,7 @@ An additional advantage of using Rust's indexing conventions for these types is
that these types can now also support Rust's indexing operators as part of a
consistent API:
```rust
```rust,ignore
#![allow(deprecated)]
use pyo3::{Python, types::PyList};

View file

@ -330,8 +330,10 @@ For a `&PyAny` object reference `any` where the underlying object is a Python-na
a list:
```rust
# #![allow(unused_imports)]
# use pyo3::prelude::*;
# use pyo3::types::PyList;
# #[cfg(feature = "gil-refs")]
# Python::with_gil(|py| -> PyResult<()> {
#[allow(deprecated)] // PyList::empty is part of the deprecated "GIL Refs" API.
let obj: &PyAny = PyList::empty(py);
@ -390,8 +392,10 @@ To see all Python types exposed by `PyO3` consult the [`pyo3::types`][pyo3::type
**Conversions:**
```rust
# #![allow(unused_imports)]
# use pyo3::prelude::*;
# use pyo3::types::PyList;
# #[cfg(feature = "gil-refs")]
# Python::with_gil(|py| -> PyResult<()> {
#[allow(deprecated)] // PyList::empty is part of the deprecated "GIL Refs" API.
let list = PyList::empty(py);

View file

@ -58,12 +58,10 @@ impl PyList {
/// Deprecated form of [`PyList::new_bound`].
#[inline]
#[track_caller]
#[cfg_attr(
not(feature = "gil-refs"),
deprecated(
since = "0.21.0",
note = "`PyList::new` will be replaced by `PyList::new_bound` in a future PyO3 version"
)
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyList::new` will be replaced by `PyList::new_bound` in a future PyO3 version"
)]
pub fn new<T, U>(py: Python<'_>, elements: impl IntoIterator<Item = T, IntoIter = U>) -> &PyList
where
@ -113,12 +111,10 @@ impl PyList {
/// Deprecated form of [`PyList::empty_bound`].
#[inline]
#[cfg_attr(
not(feature = "gil-refs"),
deprecated(
since = "0.21.0",
note = "`PyList::empty` will be replaced by `PyList::empty_bound` in a future PyO3 version"
)
#[cfg(feature = "gil-refs")]
#[deprecated(
since = "0.21.0",
note = "`PyList::empty` will be replaced by `PyList::empty_bound` in a future PyO3 version"
)]
pub fn empty(py: Python<'_>) -> &PyList {
Self::empty_bound(py).into_gil_ref()
@ -721,7 +717,6 @@ impl<'py> IntoIterator for &Bound<'py, PyList> {
}
#[cfg(test)]
#[cfg_attr(not(feature = "gil-refs"), allow(deprecated))]
mod tests {
use crate::types::any::PyAnyMethods;
use crate::types::list::PyListMethods;
@ -733,18 +728,18 @@ mod tests {
#[test]
fn test_new() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5, 7]);
assert_eq!(2, list[0].extract::<i32>().unwrap());
assert_eq!(3, list[1].extract::<i32>().unwrap());
assert_eq!(5, list[2].extract::<i32>().unwrap());
assert_eq!(7, list[3].extract::<i32>().unwrap());
let list = PyList::new_bound(py, [2, 3, 5, 7]);
assert_eq!(2, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert_eq!(3, list.get_item(1).unwrap().extract::<i32>().unwrap());
assert_eq!(5, list.get_item(2).unwrap().extract::<i32>().unwrap());
assert_eq!(7, list.get_item(3).unwrap().extract::<i32>().unwrap());
});
}
#[test]
fn test_len() {
Python::with_gil(|py| {
let list = PyList::new(py, [1, 2, 3, 4]);
let list = PyList::new_bound(py, [1, 2, 3, 4]);
assert_eq!(4, list.len());
});
}
@ -752,7 +747,7 @@ mod tests {
#[test]
fn test_get_item() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5, 7]);
let list = PyList::new_bound(py, [2, 3, 5, 7]);
assert_eq!(2, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert_eq!(3, list.get_item(1).unwrap().extract::<i32>().unwrap());
assert_eq!(5, list.get_item(2).unwrap().extract::<i32>().unwrap());
@ -763,7 +758,7 @@ mod tests {
#[test]
fn test_get_slice() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5, 7]);
let list = PyList::new_bound(py, [2, 3, 5, 7]);
let slice = list.get_slice(1, 3);
assert_eq!(2, slice.len());
let slice = list.get_slice(1, 7);
@ -774,12 +769,12 @@ mod tests {
#[test]
fn test_set_item() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5, 7]);
let list = PyList::new_bound(py, [2, 3, 5, 7]);
let val = 42i32.to_object(py);
let val2 = 42i32.to_object(py);
assert_eq!(2, list[0].extract::<i32>().unwrap());
assert_eq!(2, list.get_item(0).unwrap().extract::<i32>().unwrap());
list.set_item(0, val).unwrap();
assert_eq!(42, list[0].extract::<i32>().unwrap());
assert_eq!(42, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert!(list.set_item(10, val2).is_err());
});
}
@ -787,15 +782,14 @@ mod tests {
#[test]
fn test_set_item_refcnt() {
Python::with_gil(|py| {
let obj = py.eval("object()", None, None).unwrap();
let obj = py.eval_bound("object()", None, None).unwrap();
let cnt;
{
let _pool = unsafe { crate::GILPool::new() };
let v = vec![2];
let ob = v.to_object(py);
let list: &PyList = ob.downcast(py).unwrap();
let list = ob.downcast_bound::<PyList>(py).unwrap();
cnt = obj.get_refcnt();
list.set_item(0, obj).unwrap();
list.set_item(0, &obj).unwrap();
}
assert_eq!(cnt, obj.get_refcnt());
@ -805,17 +799,17 @@ mod tests {
#[test]
fn test_insert() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5, 7]);
let list = PyList::new_bound(py, [2, 3, 5, 7]);
let val = 42i32.to_object(py);
let val2 = 43i32.to_object(py);
assert_eq!(4, list.len());
assert_eq!(2, list[0].extract::<i32>().unwrap());
assert_eq!(2, list.get_item(0).unwrap().extract::<i32>().unwrap());
list.insert(0, val).unwrap();
list.insert(1000, val2).unwrap();
assert_eq!(6, list.len());
assert_eq!(42, list[0].extract::<i32>().unwrap());
assert_eq!(2, list[1].extract::<i32>().unwrap());
assert_eq!(43, list[5].extract::<i32>().unwrap());
assert_eq!(42, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert_eq!(2, list.get_item(1).unwrap().extract::<i32>().unwrap());
assert_eq!(43, list.get_item(5).unwrap().extract::<i32>().unwrap());
});
}
@ -823,12 +817,11 @@ mod tests {
fn test_insert_refcnt() {
Python::with_gil(|py| {
let cnt;
let obj = py.eval("object()", None, None).unwrap();
let obj = py.eval_bound("object()", None, None).unwrap();
{
let _pool = unsafe { crate::GILPool::new() };
let list = PyList::empty(py);
let list = PyList::empty_bound(py);
cnt = obj.get_refcnt();
list.insert(0, obj).unwrap();
list.insert(0, &obj).unwrap();
}
assert_eq!(cnt, obj.get_refcnt());
@ -838,10 +831,10 @@ mod tests {
#[test]
fn test_append() {
Python::with_gil(|py| {
let list = PyList::new(py, [2]);
let list = PyList::new_bound(py, [2]);
list.append(3).unwrap();
assert_eq!(2, list[0].extract::<i32>().unwrap());
assert_eq!(3, list[1].extract::<i32>().unwrap());
assert_eq!(2, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert_eq!(3, list.get_item(1).unwrap().extract::<i32>().unwrap());
});
}
@ -849,12 +842,11 @@ mod tests {
fn test_append_refcnt() {
Python::with_gil(|py| {
let cnt;
let obj = py.eval("object()", None, None).unwrap();
let obj = py.eval_bound("object()", None, None).unwrap();
{
let _pool = unsafe { crate::GILPool::new() };
let list = PyList::empty(py);
let list = PyList::empty_bound(py);
cnt = obj.get_refcnt();
list.append(obj).unwrap();
list.append(&obj).unwrap();
}
assert_eq!(cnt, obj.get_refcnt());
});
@ -864,7 +856,7 @@ mod tests {
fn test_iter() {
Python::with_gil(|py| {
let v = vec![2, 3, 5, 7];
let list = PyList::new(py, &v);
let list = PyList::new_bound(py, &v);
let mut idx = 0;
for el in list {
assert_eq!(v[idx], el.extract::<i32>().unwrap());
@ -879,7 +871,7 @@ mod tests {
Python::with_gil(|py| {
let v = vec![2, 3, 5, 7];
let ob = v.to_object(py);
let list: &PyList = ob.downcast(py).unwrap();
let list = ob.downcast_bound::<PyList>(py).unwrap();
let mut iter = list.iter();
assert_eq!(iter.size_hint(), (v.len(), Some(v.len())));
@ -898,7 +890,7 @@ mod tests {
Python::with_gil(|py| {
let v = vec![2, 3, 5, 7];
let ob = v.to_object(py);
let list: &PyList = ob.downcast(py).unwrap();
let list = ob.downcast_bound::<PyList>(py).unwrap();
let mut iter = list.iter().rev();
@ -924,7 +916,7 @@ mod tests {
#[test]
fn test_into_iter() {
Python::with_gil(|py| {
let list = PyList::new(py, [1, 2, 3, 4]);
let list = PyList::new_bound(py, [1, 2, 3, 4]);
for (i, item) in list.iter().enumerate() {
assert_eq!((i + 1) as i32, item.extract::<i32>().unwrap());
}
@ -978,7 +970,7 @@ mod tests {
fn test_extract() {
Python::with_gil(|py| {
let v = vec![2, 3, 5, 7];
let list = PyList::new(py, &v);
let list = PyList::new_bound(py, &v);
let v2 = list.as_ref().extract::<Vec<i32>>().unwrap();
assert_eq!(v, v2);
});
@ -988,16 +980,16 @@ mod tests {
fn test_sort() {
Python::with_gil(|py| {
let v = vec![7, 3, 2, 5];
let list = PyList::new(py, &v);
assert_eq!(7, list[0].extract::<i32>().unwrap());
assert_eq!(3, list[1].extract::<i32>().unwrap());
assert_eq!(2, list[2].extract::<i32>().unwrap());
assert_eq!(5, list[3].extract::<i32>().unwrap());
let list = PyList::new_bound(py, &v);
assert_eq!(7, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert_eq!(3, list.get_item(1).unwrap().extract::<i32>().unwrap());
assert_eq!(2, list.get_item(2).unwrap().extract::<i32>().unwrap());
assert_eq!(5, list.get_item(3).unwrap().extract::<i32>().unwrap());
list.sort().unwrap();
assert_eq!(2, list[0].extract::<i32>().unwrap());
assert_eq!(3, list[1].extract::<i32>().unwrap());
assert_eq!(5, list[2].extract::<i32>().unwrap());
assert_eq!(7, list[3].extract::<i32>().unwrap());
assert_eq!(2, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert_eq!(3, list.get_item(1).unwrap().extract::<i32>().unwrap());
assert_eq!(5, list.get_item(2).unwrap().extract::<i32>().unwrap());
assert_eq!(7, list.get_item(3).unwrap().extract::<i32>().unwrap());
});
}
@ -1005,16 +997,16 @@ mod tests {
fn test_reverse() {
Python::with_gil(|py| {
let v = vec![2, 3, 5, 7];
let list = PyList::new(py, &v);
assert_eq!(2, list[0].extract::<i32>().unwrap());
assert_eq!(3, list[1].extract::<i32>().unwrap());
assert_eq!(5, list[2].extract::<i32>().unwrap());
assert_eq!(7, list[3].extract::<i32>().unwrap());
let list = PyList::new_bound(py, &v);
assert_eq!(2, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert_eq!(3, list.get_item(1).unwrap().extract::<i32>().unwrap());
assert_eq!(5, list.get_item(2).unwrap().extract::<i32>().unwrap());
assert_eq!(7, list.get_item(3).unwrap().extract::<i32>().unwrap());
list.reverse().unwrap();
assert_eq!(7, list[0].extract::<i32>().unwrap());
assert_eq!(5, list[1].extract::<i32>().unwrap());
assert_eq!(3, list[2].extract::<i32>().unwrap());
assert_eq!(2, list[3].extract::<i32>().unwrap());
assert_eq!(7, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert_eq!(5, list.get_item(1).unwrap().extract::<i32>().unwrap());
assert_eq!(3, list.get_item(2).unwrap().extract::<i32>().unwrap());
assert_eq!(2, list.get_item(3).unwrap().extract::<i32>().unwrap());
});
}
@ -1022,16 +1014,16 @@ mod tests {
fn test_array_into_py() {
Python::with_gil(|py| {
let array: PyObject = [1, 2].into_py(py);
let list: &PyList = array.downcast(py).unwrap();
assert_eq!(1, list[0].extract::<i32>().unwrap());
assert_eq!(2, list[1].extract::<i32>().unwrap());
let list = array.downcast_bound::<PyList>(py).unwrap();
assert_eq!(1, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert_eq!(2, list.get_item(1).unwrap().extract::<i32>().unwrap());
});
}
#[test]
fn test_list_get_item_invalid_index() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5, 7]);
let list = PyList::new_bound(py, [2, 3, 5, 7]);
let obj = list.get_item(5);
assert!(obj.is_err());
assert_eq!(
@ -1044,7 +1036,7 @@ mod tests {
#[test]
fn test_list_get_item_sanity() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5, 7]);
let list = PyList::new_bound(py, [2, 3, 5, 7]);
let obj = list.get_item(0);
assert_eq!(obj.unwrap().extract::<i32>().unwrap(), 2);
});
@ -1054,13 +1046,15 @@ mod tests {
#[test]
fn test_list_get_item_unchecked_sanity() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5, 7]);
let list = PyList::new_bound(py, [2, 3, 5, 7]);
let obj = unsafe { list.get_item_unchecked(0) };
assert_eq!(obj.extract::<i32>().unwrap(), 2);
});
}
#[test]
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
fn test_list_index_trait() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5]);
@ -1072,6 +1066,8 @@ mod tests {
#[test]
#[should_panic]
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
fn test_list_index_trait_panic() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5]);
@ -1080,6 +1076,8 @@ mod tests {
}
#[test]
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
fn test_list_index_trait_ranges() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5]);
@ -1096,6 +1094,8 @@ mod tests {
#[test]
#[should_panic = "range start index 5 out of range for list of length 3"]
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
fn test_list_index_trait_range_panic_start() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5]);
@ -1105,6 +1105,8 @@ mod tests {
#[test]
#[should_panic = "range end index 10 out of range for list of length 3"]
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
fn test_list_index_trait_range_panic_end() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5]);
@ -1114,6 +1116,8 @@ mod tests {
#[test]
#[should_panic = "slice index starts at 2 but ends at 1"]
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
fn test_list_index_trait_range_panic_wrong_order() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5]);
@ -1124,6 +1128,8 @@ mod tests {
#[test]
#[should_panic = "range start index 8 out of range for list of length 3"]
#[cfg(feature = "gil-refs")]
#[allow(deprecated)]
fn test_list_index_trait_range_from_panic() {
Python::with_gil(|py| {
let list = PyList::new(py, [2, 3, 5]);
@ -1134,19 +1140,19 @@ mod tests {
#[test]
fn test_list_del_item() {
Python::with_gil(|py| {
let list = PyList::new(py, [1, 1, 2, 3, 5, 8]);
let list = PyList::new_bound(py, [1, 1, 2, 3, 5, 8]);
assert!(list.del_item(10).is_err());
assert_eq!(1, list[0].extract::<i32>().unwrap());
assert_eq!(1, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert!(list.del_item(0).is_ok());
assert_eq!(1, list[0].extract::<i32>().unwrap());
assert_eq!(1, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert!(list.del_item(0).is_ok());
assert_eq!(2, list[0].extract::<i32>().unwrap());
assert_eq!(2, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert!(list.del_item(0).is_ok());
assert_eq!(3, list[0].extract::<i32>().unwrap());
assert_eq!(3, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert!(list.del_item(0).is_ok());
assert_eq!(5, list[0].extract::<i32>().unwrap());
assert_eq!(5, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert!(list.del_item(0).is_ok());
assert_eq!(8, list[0].extract::<i32>().unwrap());
assert_eq!(8, list.get_item(0).unwrap().extract::<i32>().unwrap());
assert!(list.del_item(0).is_ok());
assert_eq!(0, list.len());
assert!(list.del_item(0).is_err());
@ -1156,11 +1162,11 @@ mod tests {
#[test]
fn test_list_set_slice() {
Python::with_gil(|py| {
let list = PyList::new(py, [1, 1, 2, 3, 5, 8]);
let ins = PyList::new(py, [7, 4]);
list.set_slice(1, 4, ins).unwrap();
let list = PyList::new_bound(py, [1, 1, 2, 3, 5, 8]);
let ins = PyList::new_bound(py, [7, 4]);
list.set_slice(1, 4, &ins).unwrap();
assert_eq!([1, 7, 4, 5, 8], list.extract::<[i32; 5]>().unwrap());
list.set_slice(3, 100, PyList::empty(py)).unwrap();
list.set_slice(3, 100, &PyList::empty_bound(py)).unwrap();
assert_eq!([1, 7, 4], list.extract::<[i32; 3]>().unwrap());
});
}
@ -1168,7 +1174,7 @@ mod tests {
#[test]
fn test_list_del_slice() {
Python::with_gil(|py| {
let list = PyList::new(py, [1, 1, 2, 3, 5, 8]);
let list = PyList::new_bound(py, [1, 1, 2, 3, 5, 8]);
list.del_slice(1, 4).unwrap();
assert_eq!([1, 5, 8], list.extract::<[i32; 3]>().unwrap());
list.del_slice(1, 100).unwrap();
@ -1179,7 +1185,7 @@ mod tests {
#[test]
fn test_list_contains() {
Python::with_gil(|py| {
let list = PyList::new(py, [1, 1, 2, 3, 5, 8]);
let list = PyList::new_bound(py, [1, 1, 2, 3, 5, 8]);
assert_eq!(6, list.len());
let bad_needle = 7i32.to_object(py);
@ -1196,7 +1202,7 @@ mod tests {
#[test]
fn test_list_index() {
Python::with_gil(|py| {
let list = PyList::new(py, [1, 1, 2, 3, 5, 8]);
let list = PyList::new_bound(py, [1, 1, 2, 3, 5, 8]);
assert_eq!(0, list.index(1i32).unwrap());
assert_eq!(2, list.index(2i32).unwrap());
assert_eq!(3, list.index(3i32).unwrap());
@ -1233,7 +1239,7 @@ mod tests {
fn too_long_iterator() {
Python::with_gil(|py| {
let iter = FaultyIter(0..usize::MAX, 73);
let _list = PyList::new(py, iter);
let _list = PyList::new_bound(py, iter);
})
}
@ -1244,7 +1250,7 @@ mod tests {
fn too_short_iterator() {
Python::with_gil(|py| {
let iter = FaultyIter(0..35, 73);
let _list = PyList::new(py, iter);
let _list = PyList::new_bound(py, iter);
})
}
@ -1256,7 +1262,7 @@ mod tests {
Python::with_gil(|py| {
let iter = FaultyIter(0..0, usize::MAX);
let _list = PyList::new(py, iter);
let _list = PyList::new_bound(py, iter);
})
}
@ -1315,7 +1321,7 @@ mod tests {
Python::with_gil(|py| {
std::panic::catch_unwind(|| {
let iter = FaultyIter(0..50, 50);
let _list = PyList::new(py, iter);
let _list = PyList::new_bound(py, iter);
})
.unwrap_err();
});
@ -1330,7 +1336,7 @@ mod tests {
#[test]
fn test_list_to_tuple() {
Python::with_gil(|py| {
let list = PyList::new(py, vec![1, 2, 3]);
let list = PyList::new_bound(py, vec![1, 2, 3]);
let tuple = list.to_tuple();
let tuple_expected = PyTuple::new_bound(py, vec![1, 2, 3]);
assert!(tuple.eq(tuple_expected).unwrap());