diff --git a/guide/src/migration.md b/guide/src/migration.md index 87540731..7e0420de 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -1649,7 +1649,7 @@ However, for `#[pyproto]` and some functions, you need to manually fix the code. In 0.8 object creation was done with `PyRef::new` and `PyRefMut::new`. In 0.9 these have both been removed. To upgrade code, please use -[`PyCell::new`]({{#PYO3_DOCS_URL}}/pyo3/pycell/struct.PyCell.html#method.new) instead. +`PyCell::new` instead. If you need [`PyRef`] or [`PyRefMut`], just call `.borrow()` or `.borrow_mut()` on the newly-created `PyCell`. diff --git a/guide/src/types.md b/guide/src/types.md index 20e5e76a..2a13c241 100644 --- a/guide/src/types.md +++ b/guide/src/types.md @@ -446,8 +446,10 @@ Like PyO3's Python native types, the GIL Ref `&PyCell` implements `Deref` was used to access `&T` and `&mut T` via `PyRef` and `PyRefMut` respectively. ```rust +#![allow(unused_imports)] # use pyo3::prelude::*; # #[pyclass] struct MyClass { } +# #[cfg(feature = "gil-refs")] # Python::with_gil(|py| -> PyResult<()> { #[allow(deprecated)] // &PyCell is part of the deprecated GIL Refs API let cell: &PyCell = PyCell::new(py, MyClass {})?; diff --git a/src/conversion.rs b/src/conversion.rs index 6e116af7..4df19730 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -222,9 +222,7 @@ pub trait FromPyObject<'py>: Sized { /// /// Implementors are encouraged to implement this method and leave `extract` defaulted, as /// this will be most compatible with PyO3's future API. - fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult { - Self::extract(ob.clone().into_gil_ref()) - } + fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult; /// Extracts the type hint information for this type when it appears as an argument. /// @@ -350,8 +348,8 @@ impl<'py, T> FromPyObject<'py> for &'py crate::PyCell where T: PyClass, { - fn extract(obj: &'py PyAny) -> PyResult { - obj.downcast().map_err(Into::into) + fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult { + obj.clone().into_gil_ref().downcast().map_err(Into::into) } } diff --git a/src/conversions/std/slice.rs b/src/conversions/std/slice.rs index b3932302..9c9cde06 100644 --- a/src/conversions/std/slice.rs +++ b/src/conversions/std/slice.rs @@ -20,8 +20,8 @@ impl<'a> IntoPy for &'a [u8] { #[cfg(feature = "gil-refs")] impl<'py> crate::FromPyObject<'py> for &'py [u8] { - fn extract(obj: &'py PyAny) -> PyResult { - Ok(obj.downcast::()?.as_bytes()) + fn extract_bound(obj: &crate::Bound<'py, PyAny>) -> PyResult { + Ok(obj.clone().into_gil_ref().downcast::()?.as_bytes()) } #[cfg(feature = "experimental-inspect")] diff --git a/src/conversions/std/string.rs b/src/conversions/std/string.rs index 9c276d1d..5bc05c1a 100644 --- a/src/conversions/std/string.rs +++ b/src/conversions/std/string.rs @@ -116,8 +116,8 @@ impl<'a> IntoPy for &'a String { /// Accepts Python `str` objects. #[cfg(feature = "gil-refs")] impl<'py> FromPyObject<'py> for &'py str { - fn extract(ob: &'py PyAny) -> PyResult { - ob.downcast::()?.to_str() + fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult { + ob.clone().into_gil_ref().downcast::()?.to_str() } #[cfg(feature = "experimental-inspect")] diff --git a/src/impl_/frompyobject.rs b/src/impl_/frompyobject.rs index e38ff3c7..1e46efae 100644 --- a/src/impl_/frompyobject.rs +++ b/src/impl_/frompyobject.rs @@ -4,6 +4,7 @@ use crate::{exceptions::PyTypeError, FromPyObject, PyAny, PyErr, PyResult, Pytho pub enum Extractor<'a, 'py, T> { Bound(fn(&'a Bound<'py, PyAny>) -> PyResult), + #[cfg(feature = "gil-refs")] GilRef(fn(&'a PyAny) -> PyResult), } @@ -13,6 +14,7 @@ impl<'a, 'py, T> From) -> PyResult> for Extractor<'a } } +#[cfg(feature = "gil-refs")] impl<'a, T> From PyResult> for Extractor<'a, '_, T> { fn from(value: fn(&'a PyAny) -> PyResult) -> Self { Self::GilRef(value) @@ -23,6 +25,7 @@ impl<'a, 'py, T> Extractor<'a, 'py, T> { pub(crate) fn call(self, obj: &'a Bound<'py, PyAny>) -> PyResult { match self { Extractor::Bound(f) => f(obj), + #[cfg(feature = "gil-refs")] Extractor::GilRef(f) => f(obj.as_gil_ref()), } } diff --git a/src/impl_/pyfunction.rs b/src/impl_/pyfunction.rs index cb838fea..0be51744 100644 --- a/src/impl_/pyfunction.rs +++ b/src/impl_/pyfunction.rs @@ -1,6 +1,6 @@ use crate::{ types::{PyCFunction, PyModule}, - Borrowed, Bound, PyNativeType, PyResult, Python, + Borrowed, Bound, PyResult, Python, }; pub use crate::impl_::pymethods::PyMethodDef; @@ -37,14 +37,24 @@ impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for &'_ Borrowed<'_, ' // For Python<'py>, only the GIL Ref form exists to avoid causing type inference to kick in. // The `wrap_pyfunction_bound!` macro is needed for the Bound form. +#[cfg(feature = "gil-refs")] impl<'py> WrapPyFunctionArg<'py, &'py PyCFunction> for Python<'py> { fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<&'py PyCFunction> { PyCFunction::internal_new(self, method_def, None).map(Bound::into_gil_ref) } } +#[cfg(not(feature = "gil-refs"))] +impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for Python<'py> { + fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult> { + PyCFunction::internal_new(self, method_def, None) + } +} + +#[cfg(feature = "gil-refs")] impl<'py> WrapPyFunctionArg<'py, &'py PyCFunction> for &'py PyModule { fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<&'py PyCFunction> { + use crate::PyNativeType; PyCFunction::internal_new(self.py(), method_def, Some(&self.as_borrowed())) .map(Bound::into_gil_ref) } @@ -62,6 +72,7 @@ where } } +#[cfg(feature = "gil-refs")] impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for OnlyBound> { fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult> { PyCFunction::internal_new(self.0, method_def, None) diff --git a/src/impl_/pymethods.rs b/src/impl_/pymethods.rs index 2e9dd0ac..44b2af25 100644 --- a/src/impl_/pymethods.rs +++ b/src/impl_/pymethods.rs @@ -5,7 +5,9 @@ use crate::impl_::panic::PanicTrap; use crate::internal_tricks::extract_c_string; use crate::pycell::{PyBorrowError, PyBorrowMutError}; use crate::pyclass::boolean_struct::False; -use crate::types::{any::PyAnyMethods, PyModule, PyType}; +use crate::types::any::PyAnyMethods; +#[cfg(feature = "gil-refs")] +use crate::types::{PyModule, PyType}; use crate::{ ffi, Borrowed, Bound, DowncastError, Py, PyAny, PyClass, PyClassInitializer, PyErr, PyObject, PyRef, PyRefMut, PyResult, PyTraverseError, PyTypeCheck, PyVisit, Python, @@ -492,6 +494,7 @@ impl<'a, 'py> BoundRef<'a, 'py, PyAny> { // GIL Ref implementations for &'a T ran into trouble with orphan rules, // so explicit implementations are used instead for the two relevant types. +#[cfg(feature = "gil-refs")] impl<'a> From> for &'a PyType { #[inline] fn from(bound: BoundRef<'a, 'a, PyType>) -> Self { @@ -499,6 +502,7 @@ impl<'a> From> for &'a PyType { } } +#[cfg(feature = "gil-refs")] impl<'a> From> for &'a PyModule { #[inline] fn from(bound: BoundRef<'a, 'a, PyModule>) -> Self { @@ -507,6 +511,7 @@ impl<'a> From> for &'a PyModule { } #[allow(deprecated)] +#[cfg(feature = "gil-refs")] impl<'a, 'py, T: PyClass> From> for &'a crate::PyCell { #[inline] fn from(bound: BoundRef<'a, 'py, T>) -> Self { @@ -518,7 +523,7 @@ impl<'a, 'py, T: PyClass> TryFrom> for PyRef<'py, T> { type Error = PyBorrowError; #[inline] fn try_from(value: BoundRef<'a, 'py, T>) -> Result { - value.0.clone().into_gil_ref().try_into() + value.0.try_borrow() } } @@ -526,7 +531,7 @@ impl<'a, 'py, T: PyClass> TryFrom> for PyRe type Error = PyBorrowMutError; #[inline] fn try_from(value: BoundRef<'a, 'py, T>) -> Result { - value.0.clone().into_gil_ref().try_into() + value.0.try_borrow_mut() } } diff --git a/src/instance.rs b/src/instance.rs index e160de3a..1c510b90 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -492,6 +492,7 @@ impl<'py, T> Bound<'py, T> { /// /// This is a helper to be used for migration from the deprecated "GIL Refs" API. #[inline] + #[cfg(feature = "gil-refs")] pub fn as_gil_ref(&'py self) -> &'py T::AsRefTarget where T: HasPyGilRef, @@ -507,6 +508,7 @@ impl<'py, T> Bound<'py, T> { /// /// This is a helper to be used for migration from the deprecated "GIL Refs" API. #[inline] + #[cfg(feature = "gil-refs")] pub fn into_gil_ref(self) -> &'py T::AsRefTarget where T: HasPyGilRef, diff --git a/src/pycell.rs b/src/pycell.rs index e0088d9b..215ed7bb 100644 --- a/src/pycell.rs +++ b/src/pycell.rs @@ -201,11 +201,12 @@ use crate::pyclass::{ boolean_struct::{False, True}, PyClass, }; -use crate::pyclass_init::PyClassInitializer; use crate::type_object::{PyLayout, PySizedLayout}; use crate::types::any::PyAnyMethods; use crate::types::PyAny; -use crate::{ffi, Bound, IntoPy, PyErr, PyNativeType, PyObject, PyResult, PyTypeCheck, Python}; +use crate::{ffi, Bound, IntoPy, PyErr, PyNativeType, PyObject, PyTypeCheck, Python}; +#[cfg(feature = "gil-refs")] +use crate::{pyclass_init::PyClassInitializer, PyResult}; use std::fmt; use std::mem::ManuallyDrop; use std::ops::{Deref, DerefMut}; @@ -222,7 +223,7 @@ use self::impl_::{PyClassObject, PyClassObjectLayout}; /// # Examples /// /// This example demonstrates getting a mutable reference of the contained `PyClass`. -/// ```rust +/// ```rust,ignore /// use pyo3::prelude::*; /// /// #[pyclass] @@ -272,12 +273,10 @@ impl PyCell { /// /// 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 = "use `Bound::new(py, value)` or `Py::new(py, value)` instead of `PyCell::new(py, value)`" - ) + #[cfg(feature = "gil-refs")] + #[deprecated( + since = "0.21.0", + note = "use `Bound::new(py, value)` or `Py::new(py, value)` instead of `PyCell::new(py, value)`" )] pub fn new(py: Python<'_>, value: impl Into>) -> PyResult<&Self> { Bound::new(py, value).map(Bound::into_gil_ref) @@ -317,7 +316,7 @@ impl PyCell { /// /// # Examples /// - /// ``` + /// ```ignore /// # use pyo3::prelude::*; /// #[pyclass] /// struct Class {} @@ -347,7 +346,7 @@ impl PyCell { /// /// # Examples /// - /// ``` + /// ```ignore /// # use pyo3::prelude::*; /// #[pyclass] /// struct Class {} @@ -380,7 +379,7 @@ impl PyCell { /// /// # Examples /// - /// ``` + /// ```ignore /// # use pyo3::prelude::*; /// #[pyclass] /// struct Class {} @@ -417,7 +416,7 @@ impl PyCell { /// /// # Examples /// - /// ``` + /// ```ignore /// use std::sync::atomic::{AtomicUsize, Ordering}; /// # use pyo3::prelude::*; /// @@ -561,14 +560,14 @@ impl fmt::Debug for PyCell { } } -/// A wrapper type for an immutably borrowed value from a [`PyCell`]``. +/// A wrapper type for an immutably borrowed value from a [`Bound<'py, T>`]. /// -/// See the [`PyCell`] documentation for more information. +/// See the [`Bound`] documentation for more information. /// /// # Examples /// -/// You can use `PyRef` as an alternative to a `&self` receiver when -/// - you need to access the pointer of the `PyCell`, or +/// You can use [`PyRef`] as an alternative to a `&self` receiver when +/// - you need to access the pointer of the [`Bound`], or /// - you want to get a super class. /// ``` /// # use pyo3::prelude::*; @@ -599,7 +598,7 @@ impl fmt::Debug for PyCell { /// } /// # Python::with_gil(|py| { /// # let sub = Py::new(py, Child::new()).unwrap(); -/// # pyo3::py_run!(py, sub, "assert sub.format() == 'Caterpillar(base: Butterfly, cnt: 5)', sub.format()"); +/// # pyo3::py_run!(py, sub, "assert sub.format() == 'Caterpillar(base: Butterfly, cnt: 4)', sub.format()"); /// # }); /// ``` /// @@ -1004,101 +1003,106 @@ mod tests { #[derive(Copy, Clone, PartialEq, Eq, Debug)] struct SomeClass(i32); - #[test] - fn pycell_replace() { - Python::with_gil(|py| { - #[allow(deprecated)] - let cell = PyCell::new(py, SomeClass(0)).unwrap(); - assert_eq!(*cell.borrow(), SomeClass(0)); + #[cfg(feature = "gil-refs")] + mod deprecated { + use super::*; - let previous = cell.replace(SomeClass(123)); - assert_eq!(previous, SomeClass(0)); - assert_eq!(*cell.borrow(), SomeClass(123)); - }) - } + #[test] + fn pycell_replace() { + Python::with_gil(|py| { + #[allow(deprecated)] + let cell = PyCell::new(py, SomeClass(0)).unwrap(); + assert_eq!(*cell.borrow(), SomeClass(0)); - #[test] - #[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(); + let previous = cell.replace(SomeClass(123)); + assert_eq!(previous, SomeClass(0)); + assert_eq!(*cell.borrow(), SomeClass(123)); + }) + } - cell.replace(SomeClass(123)); - }) - } + #[test] + #[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(); - #[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)); + cell.replace(SomeClass(123)); + }) + } - let previous = cell.replace_with(|value| { - *value = SomeClass(2); - SomeClass(123) - }); - assert_eq!(previous, SomeClass(2)); - assert_eq!(*cell.borrow(), SomeClass(123)); - }) - } + #[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)); - #[test] - #[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(); + let previous = cell.replace_with(|value| { + *value = SomeClass(2); + SomeClass(123) + }); + assert_eq!(previous, SomeClass(2)); + assert_eq!(*cell.borrow(), SomeClass(123)); + }) + } - cell.replace_with(|_| SomeClass(123)); - }) - } + #[test] + #[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(); - #[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)); + cell.replace_with(|_| SomeClass(123)); + }) + } - cell.swap(cell2); - assert_eq!(*cell.borrow(), SomeClass(123)); - assert_eq!(*cell2.borrow(), SomeClass(0)); - }) - } + #[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)); - #[test] - #[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(); + cell.swap(cell2); + assert_eq!(*cell.borrow(), SomeClass(123)); + assert_eq!(*cell2.borrow(), SomeClass(0)); + }) + } - let _guard = cell.borrow(); - cell.swap(cell2); - }) - } + #[test] + #[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(); - #[test] - #[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 = cell.borrow(); + cell.swap(cell2); + }) + } - let _guard = cell2.borrow(); - cell.swap(cell2); - }) + #[test] + #[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(); + cell.swap(cell2); + }) + } } #[test] diff --git a/src/tests/hygiene/misc.rs b/src/tests/hygiene/misc.rs index 24dad7ec..7a2f5881 100644 --- a/src/tests/hygiene/misc.rs +++ b/src/tests/hygiene/misc.rs @@ -41,7 +41,10 @@ fn append_to_inittab() { #[crate::pymodule] #[pyo3(crate = "crate")] #[allow(clippy::unnecessary_wraps)] - fn module_for_inittab(_: crate::Python<'_>, _: &crate::types::PyModule) -> crate::PyResult<()> { + fn module_for_inittab( + _: crate::Python<'_>, + _: &crate::Bound<'_, crate::types::PyModule>, + ) -> crate::PyResult<()> { ::std::result::Result::Ok(()) } crate::append_to_inittab!(module_for_inittab); diff --git a/src/tests/hygiene/pymodule.rs b/src/tests/hygiene/pymodule.rs index 32b3632b..91f9808b 100644 --- a/src/tests/hygiene/pymodule.rs +++ b/src/tests/hygiene/pymodule.rs @@ -7,6 +7,7 @@ fn do_something(x: i32) -> crate::PyResult { ::std::result::Result::Ok(x) } +#[cfg(feature = "gil-refs")] #[allow(deprecated)] #[crate::pymodule] #[pyo3(crate = "crate")] @@ -14,6 +15,15 @@ fn foo(_py: crate::Python<'_>, _m: &crate::types::PyModule) -> crate::PyResult<( ::std::result::Result::Ok(()) } +#[crate::pymodule] +#[pyo3(crate = "crate")] +fn foo_bound( + _py: crate::Python<'_>, + _m: &crate::Bound<'_, crate::types::PyModule>, +) -> crate::PyResult<()> { + ::std::result::Result::Ok(()) +} + #[cfg(feature = "gil-refs")] #[allow(deprecated)] #[crate::pymodule] @@ -34,7 +44,7 @@ fn my_module_bound(m: &crate::Bound<'_, crate::types::PyModule>) -> crate::PyRes )?; as crate::types::PyModuleMethods>::add_wrapped( m, - crate::wrap_pymodule!(foo), + crate::wrap_pymodule!(foo_bound), )?; ::std::result::Result::Ok(()) diff --git a/src/types/string.rs b/src/types/string.rs index 09c59035..4f0025ac 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -6,7 +6,9 @@ use crate::py_result_ext::PyResultExt; use crate::types::any::PyAnyMethods; use crate::types::bytes::PyBytesMethods; use crate::types::PyBytes; -use crate::{ffi, Bound, IntoPy, Py, PyAny, PyNativeType, PyResult, Python}; +#[cfg(feature = "gil-refs")] +use crate::PyNativeType; +use crate::{ffi, Bound, IntoPy, Py, PyAny, PyResult, Python}; use std::borrow::Cow; use std::os::raw::c_char; use std::str; @@ -135,16 +137,6 @@ pub struct PyString(PyAny); pyobject_native_type_core!(PyString, pyobject_native_static_type_object!(ffi::PyUnicode_Type), #checkfunction=ffi::PyUnicode_Check); impl PyString { - /// Deprecated form of [`PyString::new_bound`]. - #[cfg(feature = "gil-refs")] - #[deprecated( - since = "0.21.0", - note = "`PyString::new` will be replaced by `PyString::new_bound` in a future PyO3 version" - )] - pub fn new<'py>(py: Python<'py>, s: &str) -> &'py Self { - Self::new_bound(py, s).into_gil_ref() - } - /// Creates a new Python string object. /// /// Panics if out of memory. @@ -158,16 +150,6 @@ impl PyString { } } - /// Deprecated form of [`PyString::intern_bound`]. - #[cfg(feature = "gil-refs")] - #[deprecated( - since = "0.21.0", - note = "`PyString::intern` will be replaced by `PyString::intern_bound` in a future PyO3 version" - )] - pub fn intern<'py>(py: Python<'py>, s: &str) -> &'py Self { - Self::intern_bound(py, s).into_gil_ref() - } - /// Intern the given string /// /// This will return a reference to the same Python string object if called repeatedly with the same string. @@ -188,16 +170,6 @@ impl PyString { } } - /// Deprecated form of [`PyString::from_object_bound`]. - #[cfg(feature = "gil-refs")] - #[deprecated( - since = "0.21.0", - note = "`PyString::from_object` will be replaced by `PyString::from_object_bound` in a future PyO3 version" - )] - pub fn from_object<'py>(src: &'py PyAny, encoding: &str, errors: &str) -> PyResult<&'py Self> { - Self::from_object_bound(&src.as_borrowed(), encoding, errors).map(Bound::into_gil_ref) - } - /// Attempts to create a Python string from a Python [bytes-like object]. /// /// [bytes-like object]: (https://docs.python.org/3/glossary.html#term-bytes-like-object). @@ -216,6 +188,36 @@ impl PyString { .downcast_into_unchecked() } } +} + +#[cfg(feature = "gil-refs")] +impl PyString { + /// Deprecated form of [`PyString::new_bound`]. + #[deprecated( + since = "0.21.0", + note = "`PyString::new` will be replaced by `PyString::new_bound` in a future PyO3 version" + )] + pub fn new<'py>(py: Python<'py>, s: &str) -> &'py Self { + Self::new_bound(py, s).into_gil_ref() + } + + /// Deprecated form of [`PyString::intern_bound`]. + #[deprecated( + since = "0.21.0", + note = "`PyString::intern` will be replaced by `PyString::intern_bound` in a future PyO3 version" + )] + pub fn intern<'py>(py: Python<'py>, s: &str) -> &'py Self { + Self::intern_bound(py, s).into_gil_ref() + } + + /// Deprecated form of [`PyString::from_object_bound`]. + #[deprecated( + since = "0.21.0", + note = "`PyString::from_object` will be replaced by `PyString::from_object_bound` in a future PyO3 version" + )] + pub fn from_object<'py>(src: &'py PyAny, encoding: &str, errors: &str) -> PyResult<&'py Self> { + Self::from_object_bound(&src.as_borrowed(), encoding, errors).map(Bound::into_gil_ref) + } /// Gets the Python string as a Rust UTF-8 string slice. /// diff --git a/tests/test_wrap_pyfunction_deduction.rs b/tests/test_wrap_pyfunction_deduction.rs index 845cf2a3..e2050031 100644 --- a/tests/test_wrap_pyfunction_deduction.rs +++ b/tests/test_wrap_pyfunction_deduction.rs @@ -5,6 +5,7 @@ use pyo3::{prelude::*, types::PyCFunction}; #[pyfunction] fn f() {} +#[cfg(feature = "gil-refs")] pub fn add_wrapped(wrapper: &impl Fn(Python<'_>) -> PyResult<&PyCFunction>) { let _ = wrapper; } @@ -12,7 +13,10 @@ pub fn add_wrapped(wrapper: &impl Fn(Python<'_>) -> PyResult<&PyCFunction>) { #[test] fn wrap_pyfunction_deduction() { #[allow(deprecated)] + #[cfg(feature = "gil-refs")] add_wrapped(wrap_pyfunction!(f)); + #[cfg(not(feature = "gil-refs"))] + add_wrapped_bound(wrap_pyfunction!(f)); } pub fn add_wrapped_bound(wrapper: &impl Fn(Python<'_>) -> PyResult>) {