Improve docs for Py::as_ref() and Py::into_ref()
Co-authored-by: Georg Brandl <georg@python.org>
This commit is contained in:
parent
7d0b3b386a
commit
6b3c6fdeee
|
@ -60,9 +60,12 @@ This should change very little from a usage perspective. If you implemented trai
|
|||
`PyObject` and `Py<T>`, you may find you can just remove the `PyObject` implementation.
|
||||
|
||||
### `AsPyRef` has been removed
|
||||
The only implementor of `AsPyRef` was `Py<T>`, so the `AsPyRef::as_ref` method has been moved to
|
||||
`Py::as_ref`. This should require no code changes except removing the old `use` for code which
|
||||
did not use `pyo3::prelude`.
|
||||
As `PyObject` has been changed to be just a type alias, the only remaining implementor of `AsPyRef`
|
||||
was `Py<T>`. This removed the need for a trait, so the `AsPyRef::as_ref` method has been moved to
|
||||
`Py::as_ref`.
|
||||
|
||||
This should require no code changes except removing `use pyo3::AsPyRef` for code which did not use
|
||||
`pyo3::prelude::*`.
|
||||
|
||||
Before:
|
||||
```rust,ignore
|
||||
|
|
|
@ -140,11 +140,18 @@ Can be cloned using Python reference counts with `.clone()`.
|
|||
# let py = gil.python();
|
||||
let list: Py<PyList> = PyList::empty(py).into();
|
||||
|
||||
// Access the native type using Py::as_ref(py) or Py::into_ref(py)
|
||||
// (For #[pyclass] types, these will return &PyCell<T>)
|
||||
let _: &PyList = list.as_ref(py);
|
||||
let _: &PyList = list.clone().into_ref(py);
|
||||
// Access to the native type using Py::as_ref(py) or Py::into_ref(py)
|
||||
// (For #[pyclass] types T, these will return &PyCell<T>)
|
||||
|
||||
// Py::as_ref() borrows the object
|
||||
let _: &PyList = list.as_ref(py);
|
||||
|
||||
# let list_clone = list.clone(); // Just so that the .into() example for PyObject compiles.
|
||||
// Py::into_ref() moves the reference into pyo3's "object storage"; useful for making APIs
|
||||
// which return gil-bound references.
|
||||
let _: &PyList = list.into_ref(py);
|
||||
|
||||
# let list = list_clone;
|
||||
// Convert to PyObject with .into()
|
||||
let _: PyObject = list.into();
|
||||
```
|
||||
|
|
|
@ -37,7 +37,7 @@ pub unsafe trait PyNativeType: Sized {
|
|||
///
|
||||
/// Accessing this object is thread-safe, since any access to its API requires a `Python<'py>` GIL
|
||||
/// token. There are a few different ways to use the Python object contained:
|
||||
/// - [`Py::as_ref`](#method.as_ref) to borrow a GIL-bound reference to the contained object,
|
||||
/// - [`Py::as_ref`](#method.as_ref) to borrow a GIL-bound reference to the contained object.
|
||||
/// - [`Py::borrow`](#method.borrow), [`Py::try_borrow`](#method.try_borrow),
|
||||
/// [`Py::borrow_mut`](#method.borrow_mut), or [`Py::try_borrow_mut`](#method.try_borrow_mut),
|
||||
/// to directly access a `#[pyclass]` value (which has RefCell-like behavior, see
|
||||
|
@ -48,9 +48,6 @@ pub unsafe trait PyNativeType: Sized {
|
|||
///
|
||||
/// See [the guide](https://pyo3.rs/master/types.html) for an explanation
|
||||
/// of the different Python object types.
|
||||
///
|
||||
/// `Py<T>` is implemented as a safe wrapper around `NonNull<ffi::PyObject>` with
|
||||
/// specified type information.
|
||||
#[repr(transparent)]
|
||||
pub struct Py<T>(NonNull<ffi::PyObject>, PhantomData<T>);
|
||||
|
||||
|
@ -112,32 +109,23 @@ where
|
|||
unsafe { PyNativeType::unchecked_downcast(&*any) }
|
||||
}
|
||||
|
||||
/// Similar to [`as_ref`](#method.as_ref), but instead consumes this `Py` and registers the
|
||||
/// Similar to [`as_ref`](#method.as_ref), and also consumes this `Py` and registers the
|
||||
/// Python object reference in PyO3's object storage. The reference count for the Python
|
||||
/// object will not be decreased until the GIL lifetime ends.
|
||||
///
|
||||
/// # Examples
|
||||
/// Create `&PyList` from `Py<PyList>`:
|
||||
/// ```
|
||||
/// # use pyo3::prelude::*;
|
||||
/// # use pyo3::types::PyList;
|
||||
/// # Python::with_gil(|py| {
|
||||
/// let list: Py<PyList> = PyList::empty(py).into();
|
||||
/// let list: &PyList = list.into_ref(py);
|
||||
/// assert_eq!(list.len(), 0);
|
||||
/// # });
|
||||
/// ```
|
||||
/// # Example
|
||||
///
|
||||
/// Create `&PyCell<MyClass>` from `Py<MyClass>`:
|
||||
/// Useful when returning GIL-bound references from functions. In the snippet below, note that
|
||||
/// the `'py` lifetime of the input GIL lifetime is also given to the returned reference:
|
||||
/// ```
|
||||
/// # use pyo3::prelude::*;
|
||||
/// #[pyclass]
|
||||
/// struct MyClass { }
|
||||
/// # Python::with_gil(|py| {
|
||||
/// let my_class: Py<MyClass> = Py::new(py, MyClass { }).unwrap();
|
||||
/// let my_class_cell: &PyCell<MyClass> = my_class.into_ref(py);
|
||||
/// assert!(my_class_cell.try_borrow().is_ok());
|
||||
/// # });
|
||||
/// fn new_py_any<'py>(py: Python<'py>, value: impl IntoPy<PyObject>) -> &'py PyAny {
|
||||
/// let obj: PyObject = value.into_py(py);
|
||||
///
|
||||
/// // .as_ref(py) would not be suitable here, because a reference to `obj` may not be
|
||||
/// // returned from the function.
|
||||
/// obj.into_ref(py)
|
||||
/// }
|
||||
/// ```
|
||||
pub fn into_ref(self, py: Python) -> &T::AsRefTarget {
|
||||
unsafe { py.from_owned_ptr(self.into_ptr()) }
|
||||
|
|
Loading…
Reference in a new issue