From 2f3a33fda11eb06783378db39ef3515dbb618202 Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Wed, 1 May 2024 00:00:31 +0200 Subject: [PATCH] feature gate deprecated APIs for `PyList` (#4127) --- guide/src/migration.md | 4 +- guide/src/types.md | 4 + src/types/list.rs | 190 +++++++++++++++++++++-------------------- 3 files changed, 104 insertions(+), 94 deletions(-) diff --git a/guide/src/migration.md b/guide/src/migration.md index 9c7bc15002e..ad39adfa0e8 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -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}; diff --git a/guide/src/types.md b/guide/src/types.md index 4c63d175991..82040de2c43 100644 --- a/guide/src/types.md +++ b/guide/src/types.md @@ -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); diff --git a/src/types/list.rs b/src/types/list.rs index 19dbe59510f..56f21feb133 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -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(py: Python<'_>, elements: impl IntoIterator) -> &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::().unwrap()); - assert_eq!(3, list[1].extract::().unwrap()); - assert_eq!(5, list[2].extract::().unwrap()); - assert_eq!(7, list[3].extract::().unwrap()); + let list = PyList::new_bound(py, [2, 3, 5, 7]); + assert_eq!(2, list.get_item(0).unwrap().extract::().unwrap()); + assert_eq!(3, list.get_item(1).unwrap().extract::().unwrap()); + assert_eq!(5, list.get_item(2).unwrap().extract::().unwrap()); + assert_eq!(7, list.get_item(3).unwrap().extract::().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::().unwrap()); assert_eq!(3, list.get_item(1).unwrap().extract::().unwrap()); assert_eq!(5, list.get_item(2).unwrap().extract::().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::().unwrap()); + assert_eq!(2, list.get_item(0).unwrap().extract::().unwrap()); list.set_item(0, val).unwrap(); - assert_eq!(42, list[0].extract::().unwrap()); + assert_eq!(42, list.get_item(0).unwrap().extract::().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::(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::().unwrap()); + assert_eq!(2, list.get_item(0).unwrap().extract::().unwrap()); list.insert(0, val).unwrap(); list.insert(1000, val2).unwrap(); assert_eq!(6, list.len()); - assert_eq!(42, list[0].extract::().unwrap()); - assert_eq!(2, list[1].extract::().unwrap()); - assert_eq!(43, list[5].extract::().unwrap()); + assert_eq!(42, list.get_item(0).unwrap().extract::().unwrap()); + assert_eq!(2, list.get_item(1).unwrap().extract::().unwrap()); + assert_eq!(43, list.get_item(5).unwrap().extract::().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::().unwrap()); - assert_eq!(3, list[1].extract::().unwrap()); + assert_eq!(2, list.get_item(0).unwrap().extract::().unwrap()); + assert_eq!(3, list.get_item(1).unwrap().extract::().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::().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::(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::(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::().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::>().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::().unwrap()); - assert_eq!(3, list[1].extract::().unwrap()); - assert_eq!(2, list[2].extract::().unwrap()); - assert_eq!(5, list[3].extract::().unwrap()); + let list = PyList::new_bound(py, &v); + assert_eq!(7, list.get_item(0).unwrap().extract::().unwrap()); + assert_eq!(3, list.get_item(1).unwrap().extract::().unwrap()); + assert_eq!(2, list.get_item(2).unwrap().extract::().unwrap()); + assert_eq!(5, list.get_item(3).unwrap().extract::().unwrap()); list.sort().unwrap(); - assert_eq!(2, list[0].extract::().unwrap()); - assert_eq!(3, list[1].extract::().unwrap()); - assert_eq!(5, list[2].extract::().unwrap()); - assert_eq!(7, list[3].extract::().unwrap()); + assert_eq!(2, list.get_item(0).unwrap().extract::().unwrap()); + assert_eq!(3, list.get_item(1).unwrap().extract::().unwrap()); + assert_eq!(5, list.get_item(2).unwrap().extract::().unwrap()); + assert_eq!(7, list.get_item(3).unwrap().extract::().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::().unwrap()); - assert_eq!(3, list[1].extract::().unwrap()); - assert_eq!(5, list[2].extract::().unwrap()); - assert_eq!(7, list[3].extract::().unwrap()); + let list = PyList::new_bound(py, &v); + assert_eq!(2, list.get_item(0).unwrap().extract::().unwrap()); + assert_eq!(3, list.get_item(1).unwrap().extract::().unwrap()); + assert_eq!(5, list.get_item(2).unwrap().extract::().unwrap()); + assert_eq!(7, list.get_item(3).unwrap().extract::().unwrap()); list.reverse().unwrap(); - assert_eq!(7, list[0].extract::().unwrap()); - assert_eq!(5, list[1].extract::().unwrap()); - assert_eq!(3, list[2].extract::().unwrap()); - assert_eq!(2, list[3].extract::().unwrap()); + assert_eq!(7, list.get_item(0).unwrap().extract::().unwrap()); + assert_eq!(5, list.get_item(1).unwrap().extract::().unwrap()); + assert_eq!(3, list.get_item(2).unwrap().extract::().unwrap()); + assert_eq!(2, list.get_item(3).unwrap().extract::().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::().unwrap()); - assert_eq!(2, list[1].extract::().unwrap()); + let list = array.downcast_bound::(py).unwrap(); + assert_eq!(1, list.get_item(0).unwrap().extract::().unwrap()); + assert_eq!(2, list.get_item(1).unwrap().extract::().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::().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::().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::().unwrap()); + assert_eq!(1, list.get_item(0).unwrap().extract::().unwrap()); assert!(list.del_item(0).is_ok()); - assert_eq!(1, list[0].extract::().unwrap()); + assert_eq!(1, list.get_item(0).unwrap().extract::().unwrap()); assert!(list.del_item(0).is_ok()); - assert_eq!(2, list[0].extract::().unwrap()); + assert_eq!(2, list.get_item(0).unwrap().extract::().unwrap()); assert!(list.del_item(0).is_ok()); - assert_eq!(3, list[0].extract::().unwrap()); + assert_eq!(3, list.get_item(0).unwrap().extract::().unwrap()); assert!(list.del_item(0).is_ok()); - assert_eq!(5, list[0].extract::().unwrap()); + assert_eq!(5, list.get_item(0).unwrap().extract::().unwrap()); assert!(list.del_item(0).is_ok()); - assert_eq!(8, list[0].extract::().unwrap()); + assert_eq!(8, list.get_item(0).unwrap().extract::().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());