Skip to content

Commit

Permalink
deprecate PyCell::new in favor of Py::new or Bound::new (#3872)
Browse files Browse the repository at this point in the history
* deprecate `PyCell::new` in favor of `Py::new` or `Bound::new`

* update deprecation warning

Co-authored-by: David Hewitt <mail@davidhewitt.dev>

---------

Co-authored-by: David Hewitt <mail@davidhewitt.dev>
  • Loading branch information
Icxolu and davidhewitt authored Feb 20, 2024
1 parent a939006 commit 61bc02d
Show file tree
Hide file tree
Showing 19 changed files with 104 additions and 81 deletions.
5 changes: 3 additions & 2 deletions guide/src/class.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ struct MyClass {
num: i32,
}
Python::with_gil(|py| {
# #[allow(deprecated)]
let obj = PyCell::new(py, MyClass { num: 3 }).unwrap();
{
let obj_ref = obj.borrow(); // Get PyRef
Expand Down Expand Up @@ -397,7 +398,7 @@ impl SubSubClass {
}
}
# Python::with_gil(|py| {
# let subsub = pyo3::PyCell::new(py, SubSubClass::new()).unwrap();
# let subsub = pyo3::Py::new(py, SubSubClass::new()).unwrap();
# pyo3::py_run!(py, subsub, "assert subsub.method3() == 3000");
# let subsub = SubSubClass::factory_method(py, 2).unwrap();
# let subsubsub = SubSubClass::factory_method(py, 3).unwrap();
Expand Down Expand Up @@ -441,7 +442,7 @@ impl DictWithCounter {
}
}
# Python::with_gil(|py| {
# let cnt = pyo3::PyCell::new(py, DictWithCounter::new()).unwrap();
# let cnt = pyo3::Py::new(py, DictWithCounter::new()).unwrap();
# pyo3::py_run!(py, cnt, "cnt.set('abc', 10); assert cnt['abc'] == 10")
# });
# }
Expand Down
4 changes: 2 additions & 2 deletions guide/src/class/object.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ impl Number {

# fn main() -> PyResult<()> {
# Python::with_gil(|py| {
# let x = PyCell::new(py, Number(4))?;
# let y = PyCell::new(py, Number(4))?;
# let x = &Bound::new(py, Number(4))?.into_any();
# let y = &Bound::new(py, Number(4))?.into_any();
# assert!(x.eq(y)?);
# assert!(!x.ne(y)?);
# Ok(())
Expand Down
2 changes: 1 addition & 1 deletion guide/src/class/protocols.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ impl Container {

# Python::with_gil(|py| {
# let container = Container { iter: vec![1, 2, 3, 4] };
# let inst = pyo3::PyCell::new(py, container).unwrap();
# let inst = pyo3::Py::new(py, container).unwrap();
# pyo3::py_run!(py, inst, "assert list(inst) == [1, 2, 3, 4]");
# pyo3::py_run!(py, inst, "assert list(iter(iter(inst))) == [1, 2, 3, 4]");
# });
Expand Down
4 changes: 2 additions & 2 deletions guide/src/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,7 @@ impl Names {
}
}
# Python::with_gil(|py| {
# let names = PyCell::new(py, Names::new()).unwrap();
# let names = Py::new(py, Names::new()).unwrap();
# pyo3::py_run!(py, names, r"
# try:
# names.merge(names)
Expand Down Expand Up @@ -1352,7 +1352,7 @@ let obj_ref = PyRef::new(py, MyClass {}).unwrap();
```

After:
```rust
```rust,ignore
# use pyo3::prelude::*;
# #[pyclass]
# struct MyClass {}
Expand Down
2 changes: 1 addition & 1 deletion guide/src/python_from_rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ Python::with_gil(|py| {
id: 34,
name: "Yu".to_string(),
};
let userdata = PyCell::new(py, userdata).unwrap();
let userdata = Py::new(py, userdata).unwrap();
let userdata_as_tuple = (34, "Yu");
py_run!(py, userdata userdata_as_tuple, r#"
assert repr(userdata) == "User Yu(id: 34)"
Expand Down
2 changes: 2 additions & 0 deletions guide/src/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ so it also exposes all of the methods on `PyAny`.
# use pyo3::prelude::*;
# #[pyclass] struct MyClass { }
# Python::with_gil(|py| -> PyResult<()> {
# #[allow(deprecated)]
let cell: &PyCell<MyClass> = PyCell::new(py, MyClass {})?;

// To PyRef<T> with .borrow() or .try_borrow()
Expand All @@ -265,6 +266,7 @@ let _: &mut MyClass = &mut *py_ref_mut;
# use pyo3::prelude::*;
# #[pyclass] struct MyClass { }
# Python::with_gil(|py| -> PyResult<()> {
# #[allow(deprecated)]
let cell: &PyCell<MyClass> = PyCell::new(py, MyClass {})?;

// Use methods from PyAny on PyCell<T> with Deref implementation
Expand Down
2 changes: 1 addition & 1 deletion src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
/// }
///
/// Python::with_gil(|py| {
/// let time = PyCell::new(py, Time {hour: 8, minute: 43, second: 16}).unwrap();
/// let time = Py::new(py, Time {hour: 8, minute: 43, second: 16}).unwrap();
/// let time_as_tuple = (8, 43, 16);
/// py_run!(py, time time_as_tuple, r#"
/// assert time.hour == 8
Expand Down
30 changes: 26 additions & 4 deletions src/pycell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ unsafe impl<T, U> PyLayout<T> for PyCellBase<U> where U: PySizedLayout<T> {}
///
/// # fn main() -> PyResult<()> {
/// Python::with_gil(|py| {
/// # #[allow(deprecated)]
/// let n = PyCell::new(py, Number { inner: 0 })?;
///
/// let n_mutable: &mut Number = &mut n.borrow_mut();
Expand Down Expand Up @@ -284,6 +285,13 @@ impl<T: PyClass> PyCell<T> {
///
/// In cases where the value in the cell does not need to be accessed immediately after
/// creation, consider [`Py::new`](crate::Py::new) as a more efficient alternative.
#[cfg_attr(
not(feature = "gil-refs"),
deprecated(
since = "0.21.0",
note = "part of the deprecated GIL Ref API; to migrate use `Bound::new(py, value)` or `Py::new(py, value)` instead of `PyCell::new(py, value)`"
)
)]
pub fn new(py: Python<'_>, value: impl Into<PyClassInitializer<T>>) -> PyResult<&Self> {
unsafe {
let initializer = value.into();
Expand Down Expand Up @@ -332,6 +340,7 @@ impl<T: PyClass> PyCell<T> {
/// struct Class {}
///
/// Python::with_gil(|py| {
/// # #[allow(deprecated)]
/// let c = PyCell::new(py, Class {}).unwrap();
/// {
/// let m = c.borrow_mut();
Expand Down Expand Up @@ -371,6 +380,7 @@ impl<T: PyClass> PyCell<T> {
/// #[pyclass]
/// struct Class {}
/// Python::with_gil(|py| {
/// # #[allow(deprecated)]
/// let c = PyCell::new(py, Class {}).unwrap();
/// {
/// let m = c.borrow();
Expand Down Expand Up @@ -406,6 +416,7 @@ impl<T: PyClass> PyCell<T> {
/// #[pyclass]
/// struct Class {}
/// Python::with_gil(|py| {
/// # #[allow(deprecated)]
/// let c = PyCell::new(py, Class {}).unwrap();
///
/// {
Expand Down Expand Up @@ -448,6 +459,7 @@ impl<T: PyClass> PyCell<T> {
/// Python::with_gil(|py| {
/// let counter = FrozenCounter { value: AtomicUsize::new(0) };
///
/// # #[allow(deprecated)]
/// let cell = PyCell::new(py, counter).unwrap();
///
/// cell.get().value.fetch_add(1, Ordering::Relaxed);
Expand Down Expand Up @@ -640,7 +652,7 @@ impl<T: PyClass + fmt::Debug> fmt::Debug for PyCell<T> {
/// }
/// }
/// # Python::with_gil(|py| {
/// # let sub = PyCell::new(py, Child::new()).unwrap();
/// # let sub = Py::new(py, Child::new()).unwrap();
/// # pyo3::py_run!(py, sub, "assert sub.format() == 'Caterpillar(base: Butterfly, cnt: 3)'");
/// # });
/// ```
Expand Down Expand Up @@ -739,7 +751,7 @@ where
/// }
/// }
/// # Python::with_gil(|py| {
/// # let sub = PyCell::new(py, Sub::new()).unwrap();
/// # let sub = Py::new(py, Sub::new()).unwrap();
/// # pyo3::py_run!(py, sub, "assert sub.name() == 'base1 base2 sub'")
/// # });
/// ```
Expand Down Expand Up @@ -1069,6 +1081,7 @@ mod tests {
#[test]
fn pycell_replace() {
Python::with_gil(|py| {
#[allow(deprecated)]
let cell = PyCell::new(py, SomeClass(0)).unwrap();
assert_eq!(*cell.borrow(), SomeClass(0));

Expand All @@ -1082,6 +1095,7 @@ mod tests {
#[should_panic(expected = "Already borrowed: PyBorrowMutError")]
fn pycell_replace_panic() {
Python::with_gil(|py| {
#[allow(deprecated)]
let cell = PyCell::new(py, SomeClass(0)).unwrap();
let _guard = cell.borrow();

Expand All @@ -1092,6 +1106,7 @@ mod tests {
#[test]
fn pycell_replace_with() {
Python::with_gil(|py| {
#[allow(deprecated)]
let cell = PyCell::new(py, SomeClass(0)).unwrap();
assert_eq!(*cell.borrow(), SomeClass(0));

Expand All @@ -1108,6 +1123,7 @@ mod tests {
#[should_panic(expected = "Already borrowed: PyBorrowMutError")]
fn pycell_replace_with_panic() {
Python::with_gil(|py| {
#[allow(deprecated)]
let cell = PyCell::new(py, SomeClass(0)).unwrap();
let _guard = cell.borrow();

Expand All @@ -1118,7 +1134,9 @@ mod tests {
#[test]
fn pycell_swap() {
Python::with_gil(|py| {
#[allow(deprecated)]
let cell = PyCell::new(py, SomeClass(0)).unwrap();
#[allow(deprecated)]
let cell2 = PyCell::new(py, SomeClass(123)).unwrap();
assert_eq!(*cell.borrow(), SomeClass(0));
assert_eq!(*cell2.borrow(), SomeClass(123));
Expand All @@ -1133,7 +1151,9 @@ mod tests {
#[should_panic(expected = "Already borrowed: PyBorrowMutError")]
fn pycell_swap_panic() {
Python::with_gil(|py| {
#[allow(deprecated)]
let cell = PyCell::new(py, SomeClass(0)).unwrap();
#[allow(deprecated)]
let cell2 = PyCell::new(py, SomeClass(123)).unwrap();

let _guard = cell.borrow();
Expand All @@ -1145,7 +1165,9 @@ mod tests {
#[should_panic(expected = "Already borrowed: PyBorrowMutError")]
fn pycell_swap_panic_other_borrowed() {
Python::with_gil(|py| {
#[allow(deprecated)]
let cell = PyCell::new(py, SomeClass(0)).unwrap();
#[allow(deprecated)]
let cell2 = PyCell::new(py, SomeClass(123)).unwrap();

let _guard = cell2.borrow();
Expand All @@ -1156,7 +1178,7 @@ mod tests {
#[test]
fn test_as_ptr() {
Python::with_gil(|py| {
let cell = PyCell::new(py, SomeClass(0)).unwrap();
let cell = Bound::new(py, SomeClass(0)).unwrap();
let ptr = cell.as_ptr();

assert_eq!(cell.borrow().as_ptr(), ptr);
Expand All @@ -1167,7 +1189,7 @@ mod tests {
#[test]
fn test_into_ptr() {
Python::with_gil(|py| {
let cell = PyCell::new(py, SomeClass(0)).unwrap();
let cell = Bound::new(py, SomeClass(0)).unwrap();
let ptr = cell.as_ptr();

assert_eq!(cell.borrow().into_ptr(), ptr);
Expand Down
22 changes: 11 additions & 11 deletions tests/test_arithmetics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl UnaryArithmetic {
#[test]
fn unary_arithmetic() {
Python::with_gil(|py| {
let c = PyCell::new(py, UnaryArithmetic::new(2.7)).unwrap();
let c = Py::new(py, UnaryArithmetic::new(2.7)).unwrap();
py_run!(py, c, "assert repr(-c) == 'UA(-2.7)'");
py_run!(py, c, "assert repr(+c) == 'UA(2.7)'");
py_run!(py, c, "assert repr(abs(c)) == 'UA(2.7)'");
Expand Down Expand Up @@ -77,7 +77,7 @@ impl Indexable {
#[test]
fn indexable() {
Python::with_gil(|py| {
let i = PyCell::new(py, Indexable(5)).unwrap();
let i = Py::new(py, Indexable(5)).unwrap();
py_run!(py, i, "assert int(i) == 5");
py_run!(py, i, "assert [0, 1, 2, 3, 4, 5][i] == 5");
py_run!(py, i, "assert float(i) == 5.0");
Expand Down Expand Up @@ -137,7 +137,7 @@ impl InPlaceOperations {
fn inplace_operations() {
Python::with_gil(|py| {
let init = |value, code| {
let c = PyCell::new(py, InPlaceOperations { value }).unwrap();
let c = Py::new(py, InPlaceOperations { value }).unwrap();
py_run!(py, c, code);
};

Expand Down Expand Up @@ -210,7 +210,7 @@ impl BinaryArithmetic {
#[test]
fn binary_arithmetic() {
Python::with_gil(|py| {
let c = PyCell::new(py, BinaryArithmetic {}).unwrap();
let c = Py::new(py, BinaryArithmetic {}).unwrap();
py_run!(py, c, "assert c + c == 'BA + BA'");
py_run!(py, c, "assert c.__add__(c) == 'BA + BA'");
py_run!(py, c, "assert c + 1 == 'BA + 1'");
Expand Down Expand Up @@ -238,7 +238,7 @@ fn binary_arithmetic() {

py_run!(py, c, "assert pow(c, 1, 100) == 'BA ** 1 (mod: Some(100))'");

let c: Bound<'_, PyAny> = c.extract().unwrap();
let c: Bound<'_, PyAny> = c.extract(py).unwrap();
assert_py_eq!(c.add(&c).unwrap(), "BA + BA");
assert_py_eq!(c.sub(&c).unwrap(), "BA - BA");
assert_py_eq!(c.mul(&c).unwrap(), "BA * BA");
Expand Down Expand Up @@ -297,7 +297,7 @@ impl RhsArithmetic {
#[test]
fn rhs_arithmetic() {
Python::with_gil(|py| {
let c = PyCell::new(py, RhsArithmetic {}).unwrap();
let c = Py::new(py, RhsArithmetic {}).unwrap();
py_run!(py, c, "assert c.__radd__(1) == '1 + RA'");
py_run!(py, c, "assert 1 + c == '1 + RA'");
py_run!(py, c, "assert c.__rsub__(1) == '1 - RA'");
Expand Down Expand Up @@ -426,7 +426,7 @@ impl LhsAndRhs {
#[test]
fn lhs_fellback_to_rhs() {
Python::with_gil(|py| {
let c = PyCell::new(py, LhsAndRhs {}).unwrap();
let c = Py::new(py, LhsAndRhs {}).unwrap();
// If the light hand value is `LhsAndRhs`, LHS is used.
py_run!(py, c, "assert c + 1 == 'LR + 1'");
py_run!(py, c, "assert c - 1 == 'LR - 1'");
Expand Down Expand Up @@ -494,7 +494,7 @@ impl RichComparisons2 {
#[test]
fn rich_comparisons() {
Python::with_gil(|py| {
let c = PyCell::new(py, RichComparisons {}).unwrap();
let c = Py::new(py, RichComparisons {}).unwrap();
py_run!(py, c, "assert (c < c) == 'RC < RC'");
py_run!(py, c, "assert (c < 1) == 'RC < 1'");
py_run!(py, c, "assert (1 < c) == 'RC > 1'");
Expand All @@ -519,7 +519,7 @@ fn rich_comparisons() {
#[test]
fn rich_comparisons_python_3_type_error() {
Python::with_gil(|py| {
let c2 = PyCell::new(py, RichComparisons2 {}).unwrap();
let c2 = Py::new(py, RichComparisons2 {}).unwrap();
py_expect_exception!(py, c2, "c2 < c2", PyTypeError);
py_expect_exception!(py, c2, "c2 < 1", PyTypeError);
py_expect_exception!(py, c2, "1 < c2", PyTypeError);
Expand Down Expand Up @@ -620,7 +620,7 @@ mod return_not_implemented {

fn _test_binary_dunder(dunder: &str) {
Python::with_gil(|py| {
let c2 = PyCell::new(py, RichComparisonToSelf {}).unwrap();
let c2 = Py::new(py, RichComparisonToSelf {}).unwrap();
py_run!(
py,
c2,
Expand All @@ -636,7 +636,7 @@ mod return_not_implemented {
_test_binary_dunder(dunder);

Python::with_gil(|py| {
let c2 = PyCell::new(py, RichComparisonToSelf {}).unwrap();
let c2 = Py::new(py, RichComparisonToSelf {}).unwrap();
py_expect_exception!(
py,
c2,
Expand Down
Loading

0 comments on commit 61bc02d

Please sign in to comment.