[][src]Struct pyo3::pycell::PyCell

#[repr(C)]pub struct PyCell<T: PyClass> { /* fields omitted */ }

PyCell is the container type for PyClass.

From Python side, PyCell<T> is the concrete layout of T: PyClass in the Python heap, which means we can convert *const PyClass<T> to *mut ffi::PyObject.

From Rust side, PyCell<T> is the mutable container of T. Since PyCell<T: PyClass> is always on the Python heap, we don't have the ownership of it. Thus, to mutate the data behind &PyCell<T> safely, we employ the Interior Mutability Pattern like std::cell::RefCell.

PyCell implements Deref<Target = PyAny>, so you can also call methods from PyAny when you have a PyCell<T>.

Examples

In most cases, PyCell is hidden behind #[pymethods]. However, you can construct &PyCell directly to test your pyclass in Rust code.

#[pyclass]
struct Book {
    #[pyo3(get)]
    name: &'static str,
    author: &'static str,
}
let gil = Python::acquire_gil();
let py = gil.python();
let book = Book {
    name: "The Man in the High Castle",
    author: "Philip Kindred Dick",
};
let book_cell = PyCell::new(py, book).unwrap();
// you can expose PyCell to Python snippets
pyo3::py_run!(py, book_cell, "assert book_cell.name[-6:] == 'Castle'");

You can use slf: &PyCell<Self> as an alternative self receiver of #[pymethod], though you rarely need it.

use std::collections::HashMap;
#[pyclass]
#[derive(Default)]
struct Counter {
    counter: HashMap<String, usize>
}
#[pymethods]
impl Counter {
    // You can use &mut self here, but now we use &PyCell for demonstration
    fn increment(slf: &PyCell<Self>, name: String) -> PyResult<usize> {
        let mut slf_mut = slf.try_borrow_mut()?;
        // Now a mutable reference exists so we cannot get another one
        assert!(slf.try_borrow().is_err());
        assert!(slf.try_borrow_mut().is_err());
        let counter = slf_mut.counter.entry(name).or_insert(0);
        *counter += 1;
        Ok(*counter)
    }
}

Implementations

impl<T: PyClass> PyCell<T>[src]

pub fn new(
    py: Python,
    value: impl Into<PyClassInitializer<T>>
) -> PyResult<&Self> where
    T::BaseLayout: PyBorrowFlagLayout<T::BaseType>, 
[src]

Make new PyCell on the Python heap and returns the reference of it.

pub fn borrow(&self) -> PyRef<T>[src]

Immutably borrows the value T. This borrow lasts untill the returned PyRef exists.

Panics

Panics if the value is currently mutably borrowed. For a non-panicking variant, use try_borrow.

pub fn borrow_mut(&self) -> PyRefMut<T>[src]

Mutably borrows the value T. This borrow lasts untill the returned PyRefMut exists.

Panics

Panics if the value is currently mutably borrowed. For a non-panicking variant, use try_borrow_mut.

pub fn try_borrow(&self) -> Result<PyRef<T>, PyBorrowError>[src]

Immutably borrows the value T, returning an error if the value is currently mutably borrowed. This borrow lasts untill the returned PyRef exists.

This is the non-panicking variant of borrow.

Examples

#[pyclass]
struct Class {}
let gil = Python::acquire_gil();
let py = gil.python();
let c = PyCell::new(py, Class {}).unwrap();
{
    let m = c.borrow_mut();
    assert!(c.try_borrow().is_err());
}

{
    let m = c.borrow();
    assert!(c.try_borrow().is_ok());
}

pub fn try_borrow_mut(&self) -> Result<PyRefMut<T>, PyBorrowMutError>[src]

Mutably borrows the value T, returning an error if the value is currently borrowed. This borrow lasts untill the returned PyRefMut exists.

This is the non-panicking variant of borrow_mut.

Examples

#[pyclass]
struct Class {}
let gil = Python::acquire_gil();
let py = gil.python();
let c = PyCell::new(py, Class {}).unwrap();
{
    let m = c.borrow();
    assert!(c.try_borrow_mut().is_err());
}

assert!(c.try_borrow_mut().is_ok());

pub unsafe fn try_borrow_unguarded(&self) -> Result<&T, PyBorrowError>[src]

Immutably borrows the value T, returning an error if the value is currently mutably borrowed.

Safety

This method is unsafe because it does not return a PyRef, thus leaving the borrow flag untouched. Mutably borrowing the PyCell while the reference returned by this method is alive is undefined behaviour.

Examples

#[pyclass]
struct Class {}
let gil = Python::acquire_gil();
let py = gil.python();
let c = PyCell::new(py, Class {}).unwrap();

{
    let m = c.borrow_mut();
    assert!(unsafe { c.try_borrow_unguarded() }.is_err());
}

{
    let m = c.borrow();
    assert!(unsafe { c.try_borrow_unguarded() }.is_ok());
}

pub fn replace(&self, t: T) -> T[src]

Replaces the wrapped value with a new one, returning the old value,

Panics

Panics if the value is currently borrowed.

pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> T[src]

Replaces the wrapped value with a new one computed from f, returning the old value.

Panics

Panics if the value is currently borrowed.

pub fn swap(&self, other: &Self)[src]

Swaps the wrapped value of self with the wrapped value of other.

Panics

Panics if the value in either PyCell is currently borrowed.

Methods from Deref<Target = PyAny>

pub fn downcast<T>(&self) -> Result<&T, PyDowncastError> where
    T: PyTryFrom<'py>, 
[src]

Convert this PyAny to a concrete Python type.

pub fn hasattr<N>(&self, attr_name: N) -> PyResult<bool> where
    N: ToPyObject
[src]

Determines whether this object has the given attribute.

This is equivalent to the Python expression hasattr(self, attr_name).

pub fn getattr<N>(&self, attr_name: N) -> PyResult<&PyAny> where
    N: ToPyObject
[src]

Retrieves an attribute value.

This is equivalent to the Python expression self.attr_name.

pub fn setattr<N, V>(&self, attr_name: N, value: V) -> PyResult<()> where
    N: ToBorrowedObject,
    V: ToBorrowedObject
[src]

Sets an attribute value.

This is equivalent to the Python expression self.attr_name = value.

pub fn delattr<N>(&self, attr_name: N) -> PyResult<()> where
    N: ToPyObject
[src]

Deletes an attribute.

This is equivalent to the Python expression del self.attr_name.

pub fn compare<O>(&self, other: O) -> PyResult<Ordering> where
    O: ToPyObject
[src]

Compares two Python objects.

This is equivalent to:

if self == other:
    return Equal
elif a < b:
    return Less
elif a > b:
    return Greater
else:
    raise TypeError("PyAny::compare(): All comparisons returned false")

pub fn rich_compare<O>(
    &self,
    other: O,
    compare_op: CompareOp
) -> PyResult<&PyAny> where
    O: ToPyObject
[src]

Compares two Python objects.

Depending on the value of compare_op, this is equivalent to one of the following Python expressions:

  • CompareOp::Eq: self == other
  • CompareOp::Ne: self != other
  • CompareOp::Lt: self < other
  • CompareOp::Le: self <= other
  • CompareOp::Gt: self > other
  • CompareOp::Ge: self >= other

pub fn is_callable(&self) -> bool[src]

Determines whether this object is callable.

pub fn call(
    &self,
    args: impl IntoPy<Py<PyTuple>>,
    kwargs: Option<&PyDict>
) -> PyResult<&PyAny>
[src]

Calls the object.

This is equivalent to the Python expression self(*args, **kwargs).

pub fn call0(&self) -> PyResult<&PyAny>[src]

Calls the object with only positional arguments.

This is equivalent to the Python expression self(*args).

pub fn call1(&self, args: impl IntoPy<Py<PyTuple>>) -> PyResult<&PyAny>[src]

Calls the object without arguments.

This is equivalent to the Python expression self().

pub fn call_method(
    &self,
    name: &str,
    args: impl IntoPy<Py<PyTuple>>,
    kwargs: Option<&PyDict>
) -> PyResult<&PyAny>
[src]

Calls a method on the object.

This is equivalent to the Python expression self.name(*args, **kwargs).

Example

use pyo3::types::IntoPyDict;

let gil = Python::acquire_gil();
let py = gil.python();
let list = vec![3, 6, 5, 4, 7].to_object(py);
let dict = vec![("reverse", true)].into_py_dict(py);
list.call_method(py, "sort", (), Some(dict)).unwrap();
assert_eq!(list.extract::<Vec<i32>>(py).unwrap(), vec![7, 6, 5, 4, 3]);

pub fn call_method0(&self, name: &str) -> PyResult<&PyAny>[src]

Calls a method on the object without arguments.

This is equivalent to the Python expression self.name().

pub fn call_method1(
    &self,
    name: &str,
    args: impl IntoPy<Py<PyTuple>>
) -> PyResult<&PyAny>
[src]

Calls a method on the object with only positional arguments.

This is equivalent to the Python expression self.name(*args).

pub fn is_true(&self) -> PyResult<bool>[src]

Returns whether the object is considered to be true.

This is equivalent to the Python expression bool(self).

pub fn is_none(&self) -> bool[src]

Returns whether the object is considered to be None.

This is equivalent to the Python expression self is None.

pub fn is_empty(&self) -> PyResult<bool>[src]

Returns true if the sequence or mapping has a length of 0.

This is equivalent to the Python expression len(self) == 0.

pub fn get_item<K>(&self, key: K) -> PyResult<&PyAny> where
    K: ToBorrowedObject
[src]

Gets an item from the collection.

This is equivalent to the Python expression self[key].

pub fn set_item<K, V>(&self, key: K, value: V) -> PyResult<()> where
    K: ToBorrowedObject,
    V: ToBorrowedObject
[src]

Sets a collection item value.

This is equivalent to the Python expression self[key] = value.

pub fn del_item<K>(&self, key: K) -> PyResult<()> where
    K: ToBorrowedObject
[src]

Deletes an item from the collection.

This is equivalent to the Python expression del self[key].

pub fn iter(&self) -> PyResult<PyIterator>[src]

Takes an object and returns an iterator for it.

This is typically a new iterator but if the argument is an iterator, this returns itself.

pub fn get_type(&self) -> &PyType[src]

Returns the Python type object for this object's type.

pub fn get_type_ptr(&self) -> *mut PyTypeObject[src]

Returns the Python type pointer for this object.

pub fn cast_as<'a, D>(&'a self) -> Result<&'a D, PyDowncastError> where
    D: PyTryFrom<'a>, 
[src]

Casts the PyObject to a concrete Python object type.

This can cast only to native Python types, not types implemented in Rust.

pub fn extract<'a, D>(&'a self) -> PyResult<D> where
    D: FromPyObject<'a>, 
[src]

Extracts some type from the Python object.

This is a wrapper function around FromPyObject::extract().

pub fn get_refcnt(&self) -> isize[src]

Returns the reference count for the Python object.

pub fn repr(&self) -> PyResult<&PyString>[src]

Computes the "repr" representation of self.

This is equivalent to the Python expression repr(self).

pub fn str(&self) -> PyResult<&PyString>[src]

Computes the "str" representation of self.

This is equivalent to the Python expression str(self).

pub fn hash(&self) -> PyResult<isize>[src]

Retrieves the hash code of self.

This is equivalent to the Python expression hash(obi).

pub fn len(&self) -> PyResult<usize>[src]

Returns the length of the sequence or mapping.

This is equivalent to the Python expression len(self).

pub fn dir(&self) -> &PyList[src]

Returns the list of attributes of this object.

This is equivalent to the Python expression dir(self).

Trait Implementations

impl<T: PyClass> AsPyPointer for PyCell<T>[src]

impl<T: PyClass> AsRef<PyAny> for PyCell<T>[src]

impl<T: PyClass + Debug> Debug for PyCell<T>[src]

impl<T: PyClass> Deref for PyCell<T>[src]

type Target = PyAny

The resulting type after dereferencing.

impl<'a, '_, T> From<&'_ PyCell<T>> for Py<T> where
    T: PyClass
[src]

impl<'a, T> FromPyObject<'a> for &'a PyCell<T> where
    T: PyClass
[src]

impl<T: PyClass> PyLayout<T> for PyCell<T>[src]

impl<T: PyClass> PyNativeType for PyCell<T>[src]

impl<'v, T> PyTryFrom<'v> for PyCell<T> where
    T: 'v + PyClass
[src]

impl<'_, T: PyClass> ToPyObject for &'_ PyCell<T>[src]

impl<'a, T: PyClass> TryFrom<&'a PyCell<T>> for PyRef<'a, T>[src]

type Error = PyBorrowError

The type returned in the event of a conversion error.

impl<'a, T: PyClass> TryFrom<&'a PyCell<T>> for PyRefMut<'a, T>[src]

type Error = PyBorrowMutError

The type returned in the event of a conversion error.

Auto Trait Implementations

impl<T> !RefUnwindSafe for PyCell<T>

impl<T> Send for PyCell<T> where
    T: Send,
    <T as PyTypeInfo>::BaseLayout: Send,
    <T as PyClass>::Dict: Send,
    <T as PyClass>::WeakRef: Send

impl<T> !Sync for PyCell<T>

impl<T> Unpin for PyCell<T> where
    T: Unpin,
    <T as PyTypeInfo>::BaseLayout: Unpin,
    <T as PyClass>::Dict: Unpin,
    <T as PyClass>::WeakRef: Unpin

impl<T> UnwindSafe for PyCell<T> where
    T: UnwindSafe,
    <T as PyTypeInfo>::BaseLayout: UnwindSafe,
    <T as PyClass>::Dict: UnwindSafe,
    <T as PyClass>::WeakRef: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> FromPy<T> for T[src]

impl<'p, T> FromPyPointer<'p> for T where
    T: 'p + PyNativeType
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> IntoPy<U> for T where
    U: FromPy<T>, 
[src]

impl<'v, T> PyTryFrom<'v> for T where
    T: PyTypeInfo + PyNativeType
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.