Struct pyo3::Py [−][src]
#[repr(transparent)]pub struct Py<T>(_, _);
Expand description
A GIL-independent reference to an object allocated on the Python heap.
This type does not auto-dereference to the inner object because you must prove you hold the GIL to access it. Instead, call one of its methods to access the inner object:
Py::as_ref
, to borrow a GIL-bound reference to the contained object.Py::borrow
,Py::try_borrow
,Py::borrow_mut
, orPy::try_borrow_mut
, to get a (mutable) reference to a contained pyclass, using a scheme similar to std’sRefCell
. See thePyCell
guide entry for more information.- You can call methods directly on
Py
withPy::call
,Py::call_method
and friends. These require passing in thePython<'py>
token but are otherwise similar to the corresponding methods onPyAny
.
Example: Storing Python objects in structs
As all the native Python objects only appear as references, storing them in structs doesn’t work well. For example, this won’t compile:
#[pyclass] struct Foo<'py> { inner: &'py PyDict, } impl Foo { fn new() -> Foo { let foo = Python::with_gil(|py| { // `py` will only last for this scope. // `&PyDict` derives its lifetime from `py` and // so won't be able to outlive this closure. let dict: &PyDict = PyDict::new(py); // because `Foo` contains `dict` its lifetime // is now also tied to `py`. Foo { inner: dict } }); // Foo is no longer valid. // Returning it from this function is a 💥 compiler error 💥 foo } }
Py
<T>
can be used to get around this by converting dict
into a GIL-independent reference:
#[pyclass] struct Foo { inner: Py<PyDict>, } impl Foo { fn new() -> Foo { Python::with_gil(|py| { let dict: Py<PyDict> = PyDict::new(py).into(); Foo { inner: dict } }) } }
This can also be done with other pyclasses:
#[pyclass] struct Bar {/* fields omitted */} #[pyclass] struct Foo { inner: Py<Bar>, } impl Foo { fn new() -> PyResult<Foo> { Python::with_gil(|py| { let bar: Py<Bar> = Py::new(py, Bar {})?; Ok(Foo { inner: bar }) }) } }
Example: Shared ownership of Python objects
Py<T>
can be used to share ownership of a Python object, similar to std’s Rc
<T>
.
As with Rc
<T>
, cloning it increases its reference count rather than duplicating
the underlying object.
This can be done using either Py::clone_ref
or Py
<T>
’s Clone
trait implementation.
Py::clone_ref
will be faster if you happen to be already holding the GIL.
use pyo3::prelude::*; use pyo3::types::PyDict; use pyo3::conversion::AsPyPointer; Python::with_gil(|py| { let first: Py<PyDict> = PyDict::new(py).into(); // All of these are valid syntax let second = Py::clone_ref(&first, py); let third = first.clone_ref(py); let fourth = Py::clone(&first); let fifth = first.clone(); // Disposing of our original `Py<PyDict>` just decrements the reference count. drop(first); // They all point to the same object assert_eq!(second.as_ptr(), third.as_ptr()); assert_eq!(fourth.as_ptr(), fifth.as_ptr()); assert_eq!(second.as_ptr(), fourth.as_ptr()); });
Preventing reference cycles
It is easy to accidentally create reference cycles using Py
<T>
.
The Python interpreter can break these reference cycles within pyclasses if they
implement the PyGCProtocol
. If your pyclass
contains other Python objects you should implement this protocol to avoid leaking memory.
A note on Send
and Sync
Accessing this object is threadsafe, since any access to its API requires a Python<'py>
token.
As you can only get this by acquiring the GIL, Py<...>
“implements Send
and Sync
.
Implementations
Creates a new instance Py<T>
of a #[pyclass]
on the Python heap.
Examples
use pyo3::prelude::*; #[pyclass] struct Foo {/* fields omitted */} Python::with_gil(|py| -> PyResult<Py<Foo>> { let foo: Py<Foo> = Py::new(py, Foo {})?; Ok(foo) })?;
Borrows a GIL-bound reference to the contained T
.
By binding to the GIL lifetime, this allows the GIL-bound reference to not require
Python<'py>
for any of its methods, which makes calling methods
on it more ergonomic.
For native types, this reference is &T
. For pyclasses, this is &PyCell<T>
.
Note that the lifetime of the returned reference is the shortest of &self
and
Python<'py>
.
Consider using Py::into_ref
instead if this poses a problem.
Examples
Get access to &PyList
from Py<PyList>
:
Python::with_gil(|py| { let list: Py<PyList> = PyList::empty(py).into(); let list: &PyList = list.as_ref(py); assert_eq!(list.len(), 0); });
Get access to &PyCell<MyClass>
from Py<MyClass>
:
#[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.as_ref(py); assert!(my_class_cell.try_borrow().is_ok()); });
Borrows a GIL-bound reference to the contained T
independently of the lifetime of T
.
This method is similar to as_ref
but consumes self
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.
You should prefer using as_ref
if you can as it’ll have less overhead.
Examples
Py::as_ref
’s lifetime limitation forbids creating a function that references a
variable created inside the function.
fn new_py_any<'py>(py: Python<'py>, value: impl IntoPy<Py<PyAny>>) -> &'py PyAny { let obj: Py<PyAny> = value.into_py(py); // The lifetime of the return value of this function is the shortest // of `obj` and `py`. As `obj` is owned by the current function, // Rust won't let the return value escape this function! obj.as_ref(py) }
This can be solved by using Py::into_ref
instead, which does not suffer from this issue.
Note that the lifetime of the Python<'py>
token is transferred to
the returned reference.
fn new_py_any<'py>(py: Python<'py>, value: impl IntoPy<Py<PyAny>>) -> &'py PyAny { let obj: Py<PyAny> = value.into_py(py); // This reference's lifetime is determined by `py`'s lifetime. // Because that originates from outside this function, // this return value is allowed. obj.into_ref(py) }
Immutably borrows the value T
.
This borrow lasts while the returned PyRef
exists.
Multiple immutable borrows can be taken out at the same time.
Equivalent to self.as_ref(py).borrow()
-
see PyCell::borrow
.
Examples
#[pyclass] struct Foo { inner: u8, } Python::with_gil(|py| -> PyResult<()> { let foo: Py<Foo> = Py::new(py, Foo { inner: 73 })?; let inner: &u8 = &foo.borrow(py).inner; assert_eq!(*inner, 73); Ok(()) })?;
Panics
Panics if the value is currently mutably borrowed. For a non-panicking variant, use
try_borrow
.
Mutably borrows the value T
.
This borrow lasts while the returned PyRefMut
exists.
Equivalent to self.as_ref(py).borrow_mut()
-
see PyCell::borrow_mut
.
Examples
#[pyclass] struct Foo { inner: u8, } Python::with_gil(|py| -> PyResult<()> { let foo: Py<Foo> = Py::new(py, Foo { inner: 73 })?; foo.borrow_mut(py).inner = 35; assert_eq!(foo.borrow(py).inner, 35); Ok(()) })?;
Panics
Panics if the value is currently mutably borrowed. For a non-panicking variant, use
try_borrow_mut
.
Attempts to immutably borrow the value T
, returning an error if the value is currently mutably borrowed.
The borrow lasts while the returned PyRef
exists.
This is the non-panicking variant of borrow
.
Equivalent to self.as_ref(py).borrow_mut()
-
see PyCell::try_borrow
.
pub fn try_borrow_mut<'py>(
&'py self,
py: Python<'py>
) -> Result<PyRefMut<'py, T>, PyBorrowMutError>
pub fn try_borrow_mut<'py>(
&'py self,
py: Python<'py>
) -> Result<PyRefMut<'py, T>, PyBorrowMutError>
Attempts to mutably borrow the value T
, returning an error if the value is currently borrowed.
The borrow lasts while the returned PyRefMut
exists.
This is the non-panicking variant of borrow_mut
.
Equivalent to self.as_ref(py).try_borrow_mut()
-
see PyCell::try_borrow_mut
.
Gets the reference count of the ffi::PyObject
pointer.
Makes a clone of self
.
This creates another pointer to the same object, increasing its reference count.
You should prefer using this method over Clone
if you happen to be holding the GIL already.
Examples
use pyo3::prelude::*; use pyo3::types::PyDict; use pyo3::conversion::AsPyPointer; Python::with_gil(|py| { let first: Py<PyDict> = PyDict::new(py).into(); let second = Py::clone_ref(&first, py); // Both point to the same object assert_eq!(first.as_ptr(), second.as_ptr()); });
Returns whether the object is considered to be None.
This is equivalent to the Python expression self is None
.
Returns whether the object is considered to be true.
This is equivalent to the Python expression bool(self)
.
Extracts some type from the Python object.
This is a wrapper function around FromPyObject::extract()
.
Retrieves an attribute value.
This is equivalent to the Python expression self.attr_name
.
Calls the object.
This is equivalent to the Python expression self(*args, **kwargs)
.
Calls the object with only positional arguments.
This is equivalent to the Python expression self(*args)
.
Calls the object without arguments.
This is equivalent to the Python expression self()
.
Calls a method on the object.
This is equivalent to the Python expression self.name(*args, **kwargs)
.
Calls a method on the object with only positional arguments.
This is equivalent to the Python expression self.name(*args)
.
Calls a method on the object with no arguments.
This is equivalent to the Python expression self.name()
.
Create a Py<T>
instance by taking ownership of the given FFI pointer.
If ptr
is null then the current Python exception is fetched as a PyErr
.
Safety
If non-null, ptr
must be a pointer to a Python object of type T.
Create a Py<T>
instance by taking ownership of the given FFI pointer.
If ptr
is null then None
is returned.
Safety
If non-null, ptr
must be a pointer to a Python object of type T.
Create a Py<T>
instance by creating a new reference from the given FFI pointer.
If ptr
is null then the current Python exception is fetched as a PyErr
.
Safety
ptr
must be a pointer to a Python object of type T.
Casts the PyObject to a concrete Python object type.
This can cast only to native Python types, not types implemented in Rust. For a more
flexible alternative, see Py::extract
.
Trait Implementations
If the GIL is held this increments self
’s reference count.
Otherwise this registers the Py
<T>
instance to have its reference count
incremented the next time PyO3 acquires the GIL.
Dropping a Py
instance decrements the reference count on the object by 1.
Py
However for GIL lifetime reasons, cause() cannot be implemented for Py
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
impl<'a, T> FromPyObject<'a> for Py<T> where
T: PyTypeInfo,
&'a T::AsRefTarget: FromPyObject<'a>,
T::AsRefTarget: 'a + AsPyPointer,
impl<'a, T> FromPyObject<'a> for Py<T> where
T: PyTypeInfo,
&'a T::AsRefTarget: FromPyObject<'a>,
T::AsRefTarget: 'a + AsPyPointer,
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
impl<T0: IntoPy<PyObject>, T1: IntoPy<PyObject>, T2: IntoPy<PyObject>, T3: IntoPy<PyObject>, T4: IntoPy<PyObject>, T5: IntoPy<PyObject>, T6: IntoPy<PyObject>, T7: IntoPy<PyObject>, T8: IntoPy<PyObject>, T9: IntoPy<PyObject>, T10: IntoPy<PyObject>> IntoPy<Py<PyAny>> for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
impl<T0: IntoPy<PyObject>, T1: IntoPy<PyObject>, T2: IntoPy<PyObject>, T3: IntoPy<PyObject>, T4: IntoPy<PyObject>, T5: IntoPy<PyObject>, T6: IntoPy<PyObject>, T7: IntoPy<PyObject>, T8: IntoPy<PyObject>, T9: IntoPy<PyObject>, T10: IntoPy<PyObject>> IntoPy<Py<PyAny>> for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
impl<T0: IntoPy<PyObject>, T1: IntoPy<PyObject>, T2: IntoPy<PyObject>, T3: IntoPy<PyObject>, T4: IntoPy<PyObject>, T5: IntoPy<PyObject>, T6: IntoPy<PyObject>, T7: IntoPy<PyObject>, T8: IntoPy<PyObject>, T9: IntoPy<PyObject>, T10: IntoPy<PyObject>, T11: IntoPy<PyObject>> IntoPy<Py<PyAny>> for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
impl<T0: IntoPy<PyObject>, T1: IntoPy<PyObject>, T2: IntoPy<PyObject>, T3: IntoPy<PyObject>, T4: IntoPy<PyObject>, T5: IntoPy<PyObject>, T6: IntoPy<PyObject>, T7: IntoPy<PyObject>, T8: IntoPy<PyObject>, T9: IntoPy<PyObject>, T10: IntoPy<PyObject>, T11: IntoPy<PyObject>> IntoPy<Py<PyAny>> for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Converts ()
to an empty Python tuple.
impl<T0: IntoPy<PyObject>, T1: IntoPy<PyObject>, T2: IntoPy<PyObject>, T3: IntoPy<PyObject>, T4: IntoPy<PyObject>, T5: IntoPy<PyObject>, T6: IntoPy<PyObject>, T7: IntoPy<PyObject>, T8: IntoPy<PyObject>, T9: IntoPy<PyObject>, T10: IntoPy<PyObject>> IntoPy<Py<PyTuple>> for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
impl<T0: IntoPy<PyObject>, T1: IntoPy<PyObject>, T2: IntoPy<PyObject>, T3: IntoPy<PyObject>, T4: IntoPy<PyObject>, T5: IntoPy<PyObject>, T6: IntoPy<PyObject>, T7: IntoPy<PyObject>, T8: IntoPy<PyObject>, T9: IntoPy<PyObject>, T10: IntoPy<PyObject>> IntoPy<Py<PyTuple>> for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
impl<T0: IntoPy<PyObject>, T1: IntoPy<PyObject>, T2: IntoPy<PyObject>, T3: IntoPy<PyObject>, T4: IntoPy<PyObject>, T5: IntoPy<PyObject>, T6: IntoPy<PyObject>, T7: IntoPy<PyObject>, T8: IntoPy<PyObject>, T9: IntoPy<PyObject>, T10: IntoPy<PyObject>, T11: IntoPy<PyObject>> IntoPy<Py<PyTuple>> for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
impl<T0: IntoPy<PyObject>, T1: IntoPy<PyObject>, T2: IntoPy<PyObject>, T3: IntoPy<PyObject>, T4: IntoPy<PyObject>, T5: IntoPy<PyObject>, T6: IntoPy<PyObject>, T7: IntoPy<PyObject>, T8: IntoPy<PyObject>, T9: IntoPy<PyObject>, T10: IntoPy<PyObject>, T11: IntoPy<PyObject>> IntoPy<Py<PyTuple>> for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Performs the conversion.
Auto Trait Implementations
impl<T> RefUnwindSafe for Py<T> where
T: RefUnwindSafe,
impl<T> UnwindSafe for Py<T> where
T: UnwindSafe,
Blanket Implementations
Mutably borrows from an owned value. Read more