feature gate `as/into_gil_ref` APIs (Part 3) (#4172)
This commit is contained in:
parent
aef0a05719
commit
1e8e09dce3
|
@ -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.8 object creation was done with `PyRef::new` and `PyRefMut::new`.
|
||||||
In 0.9 these have both been removed.
|
In 0.9 these have both been removed.
|
||||||
To upgrade code, please use
|
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()`
|
If you need [`PyRef`] or [`PyRefMut`], just call `.borrow()` or `.borrow_mut()`
|
||||||
on the newly-created `PyCell`.
|
on the newly-created `PyCell`.
|
||||||
|
|
||||||
|
|
|
@ -446,8 +446,10 @@ Like PyO3's Python native types, the GIL Ref `&PyCell<T>` implements `Deref<Targ
|
||||||
`PyCell<T>` was used to access `&T` and `&mut T` via `PyRef<T>` and `PyRefMut<T>` respectively.
|
`PyCell<T>` was used to access `&T` and `&mut T` via `PyRef<T>` and `PyRefMut<T>` respectively.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
#![allow(unused_imports)]
|
||||||
# use pyo3::prelude::*;
|
# use pyo3::prelude::*;
|
||||||
# #[pyclass] struct MyClass { }
|
# #[pyclass] struct MyClass { }
|
||||||
|
# #[cfg(feature = "gil-refs")]
|
||||||
# Python::with_gil(|py| -> PyResult<()> {
|
# Python::with_gil(|py| -> PyResult<()> {
|
||||||
#[allow(deprecated)] // &PyCell is part of the deprecated GIL Refs API
|
#[allow(deprecated)] // &PyCell is part of the deprecated GIL Refs API
|
||||||
let cell: &PyCell<MyClass> = PyCell::new(py, MyClass {})?;
|
let cell: &PyCell<MyClass> = PyCell::new(py, MyClass {})?;
|
||||||
|
|
|
@ -222,9 +222,7 @@ pub trait FromPyObject<'py>: Sized {
|
||||||
///
|
///
|
||||||
/// Implementors are encouraged to implement this method and leave `extract` defaulted, as
|
/// Implementors are encouraged to implement this method and leave `extract` defaulted, as
|
||||||
/// this will be most compatible with PyO3's future API.
|
/// this will be most compatible with PyO3's future API.
|
||||||
fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self> {
|
fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self>;
|
||||||
Self::extract(ob.clone().into_gil_ref())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extracts the type hint information for this type when it appears as an argument.
|
/// 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<T>
|
||||||
where
|
where
|
||||||
T: PyClass,
|
T: PyClass,
|
||||||
{
|
{
|
||||||
fn extract(obj: &'py PyAny) -> PyResult<Self> {
|
fn extract_bound(obj: &Bound<'py, PyAny>) -> PyResult<Self> {
|
||||||
obj.downcast().map_err(Into::into)
|
obj.clone().into_gil_ref().downcast().map_err(Into::into)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@ impl<'a> IntoPy<PyObject> for &'a [u8] {
|
||||||
|
|
||||||
#[cfg(feature = "gil-refs")]
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> crate::FromPyObject<'py> for &'py [u8] {
|
impl<'py> crate::FromPyObject<'py> for &'py [u8] {
|
||||||
fn extract(obj: &'py PyAny) -> PyResult<Self> {
|
fn extract_bound(obj: &crate::Bound<'py, PyAny>) -> PyResult<Self> {
|
||||||
Ok(obj.downcast::<PyBytes>()?.as_bytes())
|
Ok(obj.clone().into_gil_ref().downcast::<PyBytes>()?.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "experimental-inspect")]
|
#[cfg(feature = "experimental-inspect")]
|
||||||
|
|
|
@ -116,8 +116,8 @@ impl<'a> IntoPy<PyObject> for &'a String {
|
||||||
/// Accepts Python `str` objects.
|
/// Accepts Python `str` objects.
|
||||||
#[cfg(feature = "gil-refs")]
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> FromPyObject<'py> for &'py str {
|
impl<'py> FromPyObject<'py> for &'py str {
|
||||||
fn extract(ob: &'py PyAny) -> PyResult<Self> {
|
fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult<Self> {
|
||||||
ob.downcast::<PyString>()?.to_str()
|
ob.clone().into_gil_ref().downcast::<PyString>()?.to_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "experimental-inspect")]
|
#[cfg(feature = "experimental-inspect")]
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::{exceptions::PyTypeError, FromPyObject, PyAny, PyErr, PyResult, Pytho
|
||||||
|
|
||||||
pub enum Extractor<'a, 'py, T> {
|
pub enum Extractor<'a, 'py, T> {
|
||||||
Bound(fn(&'a Bound<'py, PyAny>) -> PyResult<T>),
|
Bound(fn(&'a Bound<'py, PyAny>) -> PyResult<T>),
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
GilRef(fn(&'a PyAny) -> PyResult<T>),
|
GilRef(fn(&'a PyAny) -> PyResult<T>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +14,7 @@ impl<'a, 'py, T> From<fn(&'a Bound<'py, PyAny>) -> PyResult<T>> for Extractor<'a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a, T> From<fn(&'a PyAny) -> PyResult<T>> for Extractor<'a, '_, T> {
|
impl<'a, T> From<fn(&'a PyAny) -> PyResult<T>> for Extractor<'a, '_, T> {
|
||||||
fn from(value: fn(&'a PyAny) -> PyResult<T>) -> Self {
|
fn from(value: fn(&'a PyAny) -> PyResult<T>) -> Self {
|
||||||
Self::GilRef(value)
|
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<T> {
|
pub(crate) fn call(self, obj: &'a Bound<'py, PyAny>) -> PyResult<T> {
|
||||||
match self {
|
match self {
|
||||||
Extractor::Bound(f) => f(obj),
|
Extractor::Bound(f) => f(obj),
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
Extractor::GilRef(f) => f(obj.as_gil_ref()),
|
Extractor::GilRef(f) => f(obj.as_gil_ref()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{PyCFunction, PyModule},
|
types::{PyCFunction, PyModule},
|
||||||
Borrowed, Bound, PyNativeType, PyResult, Python,
|
Borrowed, Bound, PyResult, Python,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::impl_::pymethods::PyMethodDef;
|
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.
|
// 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.
|
// The `wrap_pyfunction_bound!` macro is needed for the Bound form.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> WrapPyFunctionArg<'py, &'py PyCFunction> for Python<'py> {
|
impl<'py> WrapPyFunctionArg<'py, &'py PyCFunction> for Python<'py> {
|
||||||
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<&'py PyCFunction> {
|
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<&'py PyCFunction> {
|
||||||
PyCFunction::internal_new(self, method_def, None).map(Bound::into_gil_ref)
|
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<Bound<'py, PyCFunction>> {
|
||||||
|
PyCFunction::internal_new(self, method_def, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> WrapPyFunctionArg<'py, &'py PyCFunction> for &'py PyModule {
|
impl<'py> WrapPyFunctionArg<'py, &'py PyCFunction> for &'py PyModule {
|
||||||
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<&'py PyCFunction> {
|
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<&'py PyCFunction> {
|
||||||
|
use crate::PyNativeType;
|
||||||
PyCFunction::internal_new(self.py(), method_def, Some(&self.as_borrowed()))
|
PyCFunction::internal_new(self.py(), method_def, Some(&self.as_borrowed()))
|
||||||
.map(Bound::into_gil_ref)
|
.map(Bound::into_gil_ref)
|
||||||
}
|
}
|
||||||
|
@ -62,6 +72,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for OnlyBound<Python<'py>> {
|
impl<'py> WrapPyFunctionArg<'py, Bound<'py, PyCFunction>> for OnlyBound<Python<'py>> {
|
||||||
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<Bound<'py, PyCFunction>> {
|
||||||
PyCFunction::internal_new(self.0, method_def, None)
|
PyCFunction::internal_new(self.0, method_def, None)
|
||||||
|
|
|
@ -5,7 +5,9 @@ use crate::impl_::panic::PanicTrap;
|
||||||
use crate::internal_tricks::extract_c_string;
|
use crate::internal_tricks::extract_c_string;
|
||||||
use crate::pycell::{PyBorrowError, PyBorrowMutError};
|
use crate::pycell::{PyBorrowError, PyBorrowMutError};
|
||||||
use crate::pyclass::boolean_struct::False;
|
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::{
|
use crate::{
|
||||||
ffi, Borrowed, Bound, DowncastError, Py, PyAny, PyClass, PyClassInitializer, PyErr, PyObject,
|
ffi, Borrowed, Bound, DowncastError, Py, PyAny, PyClass, PyClassInitializer, PyErr, PyObject,
|
||||||
PyRef, PyRefMut, PyResult, PyTraverseError, PyTypeCheck, PyVisit, Python,
|
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,
|
// GIL Ref implementations for &'a T ran into trouble with orphan rules,
|
||||||
// so explicit implementations are used instead for the two relevant types.
|
// so explicit implementations are used instead for the two relevant types.
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> From<BoundRef<'a, 'a, PyType>> for &'a PyType {
|
impl<'a> From<BoundRef<'a, 'a, PyType>> for &'a PyType {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(bound: BoundRef<'a, 'a, PyType>) -> Self {
|
fn from(bound: BoundRef<'a, 'a, PyType>) -> Self {
|
||||||
|
@ -499,6 +502,7 @@ impl<'a> From<BoundRef<'a, 'a, PyType>> for &'a PyType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a> From<BoundRef<'a, 'a, PyModule>> for &'a PyModule {
|
impl<'a> From<BoundRef<'a, 'a, PyModule>> for &'a PyModule {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(bound: BoundRef<'a, 'a, PyModule>) -> Self {
|
fn from(bound: BoundRef<'a, 'a, PyModule>) -> Self {
|
||||||
|
@ -507,6 +511,7 @@ impl<'a> From<BoundRef<'a, 'a, PyModule>> for &'a PyModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'a, 'py, T: PyClass> From<BoundRef<'a, 'py, T>> for &'a crate::PyCell<T> {
|
impl<'a, 'py, T: PyClass> From<BoundRef<'a, 'py, T>> for &'a crate::PyCell<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(bound: BoundRef<'a, 'py, T>) -> Self {
|
fn from(bound: BoundRef<'a, 'py, T>) -> Self {
|
||||||
|
@ -518,7 +523,7 @@ impl<'a, 'py, T: PyClass> TryFrom<BoundRef<'a, 'py, T>> for PyRef<'py, T> {
|
||||||
type Error = PyBorrowError;
|
type Error = PyBorrowError;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_from(value: BoundRef<'a, 'py, T>) -> Result<Self, Self::Error> {
|
fn try_from(value: BoundRef<'a, 'py, T>) -> Result<Self, Self::Error> {
|
||||||
value.0.clone().into_gil_ref().try_into()
|
value.0.try_borrow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,7 +531,7 @@ impl<'a, 'py, T: PyClass<Frozen = False>> TryFrom<BoundRef<'a, 'py, T>> for PyRe
|
||||||
type Error = PyBorrowMutError;
|
type Error = PyBorrowMutError;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_from(value: BoundRef<'a, 'py, T>) -> Result<Self, Self::Error> {
|
fn try_from(value: BoundRef<'a, 'py, T>) -> Result<Self, Self::Error> {
|
||||||
value.0.clone().into_gil_ref().try_into()
|
value.0.try_borrow_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
/// This is a helper to be used for migration from the deprecated "GIL Refs" API.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub fn as_gil_ref(&'py self) -> &'py T::AsRefTarget
|
pub fn as_gil_ref(&'py self) -> &'py T::AsRefTarget
|
||||||
where
|
where
|
||||||
T: HasPyGilRef,
|
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.
|
/// This is a helper to be used for migration from the deprecated "GIL Refs" API.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub fn into_gil_ref(self) -> &'py T::AsRefTarget
|
pub fn into_gil_ref(self) -> &'py T::AsRefTarget
|
||||||
where
|
where
|
||||||
T: HasPyGilRef,
|
T: HasPyGilRef,
|
||||||
|
|
|
@ -201,11 +201,12 @@ use crate::pyclass::{
|
||||||
boolean_struct::{False, True},
|
boolean_struct::{False, True},
|
||||||
PyClass,
|
PyClass,
|
||||||
};
|
};
|
||||||
use crate::pyclass_init::PyClassInitializer;
|
|
||||||
use crate::type_object::{PyLayout, PySizedLayout};
|
use crate::type_object::{PyLayout, PySizedLayout};
|
||||||
use crate::types::any::PyAnyMethods;
|
use crate::types::any::PyAnyMethods;
|
||||||
use crate::types::PyAny;
|
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::fmt;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
@ -222,7 +223,7 @@ use self::impl_::{PyClassObject, PyClassObjectLayout};
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// This example demonstrates getting a mutable reference of the contained `PyClass`.
|
/// This example demonstrates getting a mutable reference of the contained `PyClass`.
|
||||||
/// ```rust
|
/// ```rust,ignore
|
||||||
/// use pyo3::prelude::*;
|
/// use pyo3::prelude::*;
|
||||||
///
|
///
|
||||||
/// #[pyclass]
|
/// #[pyclass]
|
||||||
|
@ -272,12 +273,10 @@ impl<T: PyClass> PyCell<T> {
|
||||||
///
|
///
|
||||||
/// In cases where the value in the cell does not need to be accessed immediately after
|
/// 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.
|
/// creation, consider [`Py::new`](crate::Py::new) as a more efficient alternative.
|
||||||
#[cfg_attr(
|
#[cfg(feature = "gil-refs")]
|
||||||
not(feature = "gil-refs"),
|
#[deprecated(
|
||||||
deprecated(
|
|
||||||
since = "0.21.0",
|
since = "0.21.0",
|
||||||
note = "use `Bound::new(py, value)` or `Py::new(py, value)` instead of `PyCell::new(py, value)`"
|
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<PyClassInitializer<T>>) -> PyResult<&Self> {
|
pub fn new(py: Python<'_>, value: impl Into<PyClassInitializer<T>>) -> PyResult<&Self> {
|
||||||
Bound::new(py, value).map(Bound::into_gil_ref)
|
Bound::new(py, value).map(Bound::into_gil_ref)
|
||||||
|
@ -317,7 +316,7 @@ impl<T: PyClass> PyCell<T> {
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```ignore
|
||||||
/// # use pyo3::prelude::*;
|
/// # use pyo3::prelude::*;
|
||||||
/// #[pyclass]
|
/// #[pyclass]
|
||||||
/// struct Class {}
|
/// struct Class {}
|
||||||
|
@ -347,7 +346,7 @@ impl<T: PyClass> PyCell<T> {
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```ignore
|
||||||
/// # use pyo3::prelude::*;
|
/// # use pyo3::prelude::*;
|
||||||
/// #[pyclass]
|
/// #[pyclass]
|
||||||
/// struct Class {}
|
/// struct Class {}
|
||||||
|
@ -380,7 +379,7 @@ impl<T: PyClass> PyCell<T> {
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```ignore
|
||||||
/// # use pyo3::prelude::*;
|
/// # use pyo3::prelude::*;
|
||||||
/// #[pyclass]
|
/// #[pyclass]
|
||||||
/// struct Class {}
|
/// struct Class {}
|
||||||
|
@ -417,7 +416,7 @@ impl<T: PyClass> PyCell<T> {
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```ignore
|
||||||
/// use std::sync::atomic::{AtomicUsize, Ordering};
|
/// use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
/// # use pyo3::prelude::*;
|
/// # use pyo3::prelude::*;
|
||||||
///
|
///
|
||||||
|
@ -561,14 +560,14 @@ impl<T: PyClass + fmt::Debug> fmt::Debug for PyCell<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper type for an immutably borrowed value from a [`PyCell`]`<T>`.
|
/// 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
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// You can use `PyRef` as an alternative to a `&self` receiver when
|
/// You can use [`PyRef`] as an alternative to a `&self` receiver when
|
||||||
/// - you need to access the pointer of the `PyCell`, or
|
/// - you need to access the pointer of the [`Bound`], or
|
||||||
/// - you want to get a super class.
|
/// - you want to get a super class.
|
||||||
/// ```
|
/// ```
|
||||||
/// # use pyo3::prelude::*;
|
/// # use pyo3::prelude::*;
|
||||||
|
@ -599,7 +598,7 @@ impl<T: PyClass + fmt::Debug> fmt::Debug for PyCell<T> {
|
||||||
/// }
|
/// }
|
||||||
/// # Python::with_gil(|py| {
|
/// # Python::with_gil(|py| {
|
||||||
/// # let sub = Py::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: 5)', sub.format()");
|
/// # pyo3::py_run!(py, sub, "assert sub.format() == 'Caterpillar(base: Butterfly, cnt: 4)', sub.format()");
|
||||||
/// # });
|
/// # });
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
@ -1004,6 +1003,10 @@ mod tests {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||||
struct SomeClass(i32);
|
struct SomeClass(i32);
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
|
mod deprecated {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pycell_replace() {
|
fn pycell_replace() {
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
|
@ -1100,6 +1103,7 @@ mod tests {
|
||||||
cell.swap(cell2);
|
cell.swap(cell2);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_as_ptr() {
|
fn test_as_ptr() {
|
||||||
|
|
|
@ -41,7 +41,10 @@ fn append_to_inittab() {
|
||||||
#[crate::pymodule]
|
#[crate::pymodule]
|
||||||
#[pyo3(crate = "crate")]
|
#[pyo3(crate = "crate")]
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
#[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(())
|
::std::result::Result::Ok(())
|
||||||
}
|
}
|
||||||
crate::append_to_inittab!(module_for_inittab);
|
crate::append_to_inittab!(module_for_inittab);
|
||||||
|
|
|
@ -7,6 +7,7 @@ fn do_something(x: i32) -> crate::PyResult<i32> {
|
||||||
::std::result::Result::Ok(x)
|
::std::result::Result::Ok(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
#[crate::pymodule]
|
#[crate::pymodule]
|
||||||
#[pyo3(crate = "crate")]
|
#[pyo3(crate = "crate")]
|
||||||
|
@ -14,6 +15,15 @@ fn foo(_py: crate::Python<'_>, _m: &crate::types::PyModule) -> crate::PyResult<(
|
||||||
::std::result::Result::Ok(())
|
::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")]
|
#[cfg(feature = "gil-refs")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
#[crate::pymodule]
|
#[crate::pymodule]
|
||||||
|
@ -34,7 +44,7 @@ fn my_module_bound(m: &crate::Bound<'_, crate::types::PyModule>) -> crate::PyRes
|
||||||
)?;
|
)?;
|
||||||
<crate::Bound<'_, crate::types::PyModule> as crate::types::PyModuleMethods>::add_wrapped(
|
<crate::Bound<'_, crate::types::PyModule> as crate::types::PyModuleMethods>::add_wrapped(
|
||||||
m,
|
m,
|
||||||
crate::wrap_pymodule!(foo),
|
crate::wrap_pymodule!(foo_bound),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
::std::result::Result::Ok(())
|
::std::result::Result::Ok(())
|
||||||
|
|
|
@ -6,7 +6,9 @@ use crate::py_result_ext::PyResultExt;
|
||||||
use crate::types::any::PyAnyMethods;
|
use crate::types::any::PyAnyMethods;
|
||||||
use crate::types::bytes::PyBytesMethods;
|
use crate::types::bytes::PyBytesMethods;
|
||||||
use crate::types::PyBytes;
|
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::borrow::Cow;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::str;
|
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);
|
pyobject_native_type_core!(PyString, pyobject_native_static_type_object!(ffi::PyUnicode_Type), #checkfunction=ffi::PyUnicode_Check);
|
||||||
|
|
||||||
impl PyString {
|
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.
|
/// Creates a new Python string object.
|
||||||
///
|
///
|
||||||
/// Panics if out of memory.
|
/// 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
|
/// Intern the given string
|
||||||
///
|
///
|
||||||
/// This will return a reference to the same Python string object if called repeatedly with the same 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].
|
/// 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).
|
/// [bytes-like object]: (https://docs.python.org/3/glossary.html#term-bytes-like-object).
|
||||||
|
@ -216,6 +188,36 @@ impl PyString {
|
||||||
.downcast_into_unchecked()
|
.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.
|
/// Gets the Python string as a Rust UTF-8 string slice.
|
||||||
///
|
///
|
||||||
|
|
|
@ -5,6 +5,7 @@ use pyo3::{prelude::*, types::PyCFunction};
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
fn f() {}
|
fn f() {}
|
||||||
|
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
pub fn add_wrapped(wrapper: &impl Fn(Python<'_>) -> PyResult<&PyCFunction>) {
|
pub fn add_wrapped(wrapper: &impl Fn(Python<'_>) -> PyResult<&PyCFunction>) {
|
||||||
let _ = wrapper;
|
let _ = wrapper;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +13,10 @@ pub fn add_wrapped(wrapper: &impl Fn(Python<'_>) -> PyResult<&PyCFunction>) {
|
||||||
#[test]
|
#[test]
|
||||||
fn wrap_pyfunction_deduction() {
|
fn wrap_pyfunction_deduction() {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
|
#[cfg(feature = "gil-refs")]
|
||||||
add_wrapped(wrap_pyfunction!(f));
|
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<Bound<'_, PyCFunction>>) {
|
pub fn add_wrapped_bound(wrapper: &impl Fn(Python<'_>) -> PyResult<Bound<'_, PyCFunction>>) {
|
||||||
|
|
Loading…
Reference in New Issue