Update downcast documentation

This commit is contained in:
mejrs 2023-01-24 19:15:32 +01:00
parent 18081ba14e
commit fe7b1eed04
2 changed files with 78 additions and 9 deletions

View file

@ -991,10 +991,52 @@ impl<T> std::fmt::Debug for Py<T> {
pub type PyObject = Py<PyAny>;
impl PyObject {
/// Casts the PyObject to a concrete Python object type.
/// Downcast this `PyObject` to a concrete Python type or pyclass.
///
/// This can cast only to native Python types, not types implemented in Rust. For a more
/// flexible alternative, see [`Py::extract`](struct.Py.html#method.extract).
/// Note that you can often avoid downcasting yourself by just specifying
/// the desired type in function or method signatures.
/// However, manual downcasting is sometimes necessary.
///
/// For extracting a Rust-only type, see [`Py::extract`](struct.Py.html#method.extract).
///
/// # Example: Downcasting to a specific Python object
///
/// ```rust
/// use pyo3::prelude::*;
/// use pyo3::types::{PyDict, PyList};
///
/// Python::with_gil(|py| {
/// let any: PyObject = PyDict::new(py).into();
///
/// assert!(any.downcast::<PyDict>(py).is_ok());
/// assert!(any.downcast::<PyList>(py).is_err());
/// });
/// ```
///
/// # Example: Getting a reference to a pyclass
///
/// This is useful if you want to mutate a `PyObject` that
/// might actually be a pyclass.
///
/// ```
/// # fn main() -> Result<(), pyo3::PyErr> {
/// use pyo3::prelude::*;
///
/// #[pyclass]
/// struct Class {
/// i: i32,
/// }
///
/// Python::with_gil(|py| {
/// let class: PyObject = Py::new(py, Class { i: 0 }).unwrap().into_py(py);
///
/// let class_cell: &PyCell<Class> = class.downcast(py)?;
///
/// class_cell.borrow_mut().i += 1;
/// Ok(())
/// })
/// # }
/// ```
#[inline]
pub fn downcast<'p, T>(&'p self, py: Python<'p>) -> Result<&T, PyDowncastError<'_>>
where
@ -1005,9 +1047,6 @@ impl PyObject {
/// Casts the PyObject to a concrete Python object type without checking validity.
///
/// This can cast only to native Python types, not types implemented in Rust. For a more
/// flexible alternative, see [`Py::extract`](struct.Py.html#method.extract).
///
/// # Safety
///
/// Callers must ensure that the type is valid or risk type confusion.

View file

@ -755,11 +755,15 @@ impl PyAny {
self.downcast()
}
/// Converts this `PyAny` to a concrete Python type.
/// Downcast this `PyAny` to a concrete Python type or pyclass.
///
/// This can cast only to native Python types, not types implemented in Rust.
/// Note that you can often avoid downcasting yourself by just specifying
/// the desired type in function or method signatures.
/// However, manual downcasting is sometimes necessary.
///
/// # Examples
/// For extracting a Rust-only type, see [`PyAny::extract`](struct.PyAny.html#method.extract).
///
/// # Example: Downcasting to a specific Python object
///
/// ```rust
/// use pyo3::prelude::*;
@ -769,10 +773,36 @@ impl PyAny {
/// let dict = PyDict::new(py);
/// assert!(dict.is_instance_of::<PyAny>().unwrap());
/// let any: &PyAny = dict.as_ref();
///
/// assert!(any.downcast::<PyDict>().is_ok());
/// assert!(any.downcast::<PyList>().is_err());
/// });
/// ```
///
/// # Example: Getting a reference to a pyclass
///
/// This is useful if you want to mutate a `PyObject` that
/// might actually be a pyclass.
///
/// ```
/// # fn main() -> Result<(), pyo3::PyErr> {
/// use pyo3::prelude::*;
///
/// #[pyclass]
/// struct Class {
/// i: i32,
/// }
///
/// Python::with_gil(|py| {
/// let class: &PyAny = Py::new(py, Class { i: 0 }).unwrap().into_ref(py);
///
/// let class_cell: &PyCell<Class> = class.downcast()?;
///
/// class_cell.borrow_mut().i += 1;
/// Ok(())
/// })
/// # }
/// ```
#[inline]
pub fn downcast<'p, T>(&'p self) -> Result<&'p T, PyDowncastError<'_>>
where