Skip to main content

PyClassGuardMut

Struct PyClassGuardMut 

Source
pub struct PyClassGuardMut<'a, T>
where T: PyClass<Frozen = False>,
{ /* private fields */ }
Expand description

A wrapper type for a mutably borrowed value from a PyClass

§When not to use PyClassGuardMut

Usually you can use &mut references as method and function receivers and arguments, and you won’t need to use PyClassGuardMut directly:

use pyo3::prelude::*;

#[pyclass]
struct Number {
    inner: u32,
}

#[pymethods]
impl Number {
    fn increment(&mut self) {
        self.inner += 1;
    }
}

The #[pymethods] proc macro will generate this wrapper function (and more), using PyClassGuardMut under the hood:

// The function which is exported to Python looks roughly like the following
unsafe extern "C" fn __pymethod_increment__(
    _slf: *mut ::pyo3::ffi::PyObject,
    _args: *mut ::pyo3::ffi::PyObject,
) -> *mut ::pyo3::ffi::PyObject {
    unsafe fn inner<'py>(
        py: ::pyo3::Python<'py>,
        _slf: *mut ::pyo3::ffi::PyObject,
    ) -> ::pyo3::PyResult<*mut ::pyo3::ffi::PyObject> {
        let function = Number::increment;
        let mut holder_0 = ::pyo3::impl_::extract_argument::FunctionArgumentHolder::INIT;
        let result = {
            let ret = function(::pyo3::impl_::extract_argument::extract_pyclass_ref_mut::<Number>(
                unsafe { ::pyo3::impl_::extract_argument::cast_function_argument(py, _slf) },
                &mut holder_0,
            )?);
            {
                let result = {
                    let obj = ret;
                    ::pyo3::impl_::wrap::converter(&obj)
                        .wrap(obj)
                        .map_err(::core::convert::Into::<::pyo3::PyErr>::into)
                };
                ::pyo3::impl_::wrap::converter(&result).map_into_ptr(py, result)
            }
        };
        result
    }

    unsafe {
        ::pyo3::impl_::trampoline::get_trampoline_function!(noargs, inner)(
            _slf,
            _args,
        )
    }
}

§When to use PyClassGuardMut

§Using PyClasses from Rust

However, we do need PyClassGuardMut if we want to call its methods from Rust:

Python::attach(|py| {
    let n = Py::new(py, Number { inner: 0 })?;

    // We borrow the guard and then dereference
    // it to get a mutable reference to Number
    let mut guard: PyClassGuardMut<'_, Number> = n.extract(py)?;
    let n_mutable: &mut Number = &mut *guard;

    n_mutable.increment();

    // To avoid panics we must dispose of the
    // `PyClassGuardMut` before borrowing again.
    drop(guard);

    let n_immutable: &Number = &*n.extract::<PyClassGuard<'_, Number>>(py)?;
    assert_eq!(n_immutable.inner, 1);

    Ok(())
})

§Dealing with possibly overlapping mutable references

It is also necessary to use PyClassGuardMut if you can receive mutable arguments that may overlap. Suppose the following function that swaps the values of two Numbers:

#[pyfunction]
fn swap_numbers(a: &mut Number, b: &mut Number) {
    core::mem::swap(&mut a.inner, &mut b.inner);
}

When users pass in the same Number as both arguments, one of the mutable borrows will fail and raise a RuntimeError:

>>> a = Number()
>>> swap_numbers(a, a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  RuntimeError: Already borrowed

It is better to write that function like this:

#[pyfunction]
fn swap_numbers(a: &Bound<'_, Number>, b: &Bound<'_, Number>) -> PyResult<()> {
    // Check that the pointers are unequal
    if !a.is(b) {
        let mut a: PyClassGuardMut<'_, Number> = a.extract()?;
        let mut b: PyClassGuardMut<'_, Number> = b.extract()?;
        core::mem::swap(&mut a.inner, &mut b.inner);
    } else {
        // Do nothing - they are the same object, so don't need swapping.
    }
    Ok(())
}

See PyClassGuard and the guide for more information.

Implementations§

Source§

impl<'a, T> PyClassGuardMut<'a, T>
where T: PyClass<Frozen = False>,

Source

pub fn map<F, U>(self, f: F) -> PyClassGuardMapMut<'a, U>
where F: FnOnce(&mut T) -> &mut U, U: ?Sized,

Consumes the PyClassGuardMut and returns a PyClassGuardMap for a component of the borrowed data

§Examples

#[pyclass]
pub struct MyClass {
    data: [i32; 100],
}

let obj = Bound::new(py, MyClass { data: [0; 100] })?;
let mut data = obj.extract::<PyClassGuardMut<'_, MyClass>>()?.map(|c| c.data.as_mut_slice());
data[0] = 42;
Source§

impl<'a, T> PyClassGuardMut<'a, T>
where <T as PyClassImpl>::BaseType: PyClass<Frozen = False>, T: PyClass<Frozen = False>,

Source

pub fn as_super( &mut self, ) -> PyClassGuardMutSuper<'_, 'a, <T as PyClassImpl>::BaseType>

Borrows a mutable reference to PyClassGuardMut<T::BaseType>.

With the help of this method, you can mutate attributes and call mutating methods on the superclass without consuming the PyClassGuardMut<T>. This method can also be chained to access the super-superclass (and so on).

See PyClassGuard::as_super for more.

§Note

The mutable reference to the base type is not exposed directly, but through PyClassGuardMutSuper.

Source

pub fn into_super(self) -> PyClassGuardMut<'a, <T as PyClassImpl>::BaseType>

Gets a PyClassGuardMut<T::BaseType>.

See PyClassGuard::into_super for more.

Trait Implementations§

Source§

impl<T> Debug for PyClassGuardMut<'_, T>
where T: PyClass<Frozen = False> + Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<T> Deref for PyClassGuardMut<'_, T>
where T: PyClass<Frozen = False>,

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &T

Dereferences the value.
Source§

impl<T> DerefMut for PyClassGuardMut<'_, T>
where T: PyClass<Frozen = False>,

Source§

fn deref_mut(&mut self) -> &mut T

Mutably dereferences the value.
Source§

impl<T> Drop for PyClassGuardMut<'_, T>
where T: PyClass<Frozen = False>,

Source§

fn drop(&mut self)

Releases the mutable borrow

Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl<'a, 'py, T> FromPyObject<'a, 'py> for PyClassGuardMut<'a, T>
where T: PyClass<Frozen = False>,

Source§

type Error = PyClassGuardMutError<'a, 'py>

The type returned in the event of a conversion error. Read more
Source§

fn extract( obj: Borrowed<'a, 'py, PyAny>, ) -> Result<PyClassGuardMut<'a, T>, <PyClassGuardMut<'a, T> as FromPyObject<'a, 'py>>::Error>

Extracts Self from the bound smart pointer obj. Read more
Source§

impl<'a, 'py, T> IntoPyObject<'py> for PyClassGuardMut<'a, T>
where T: PyClass<Frozen = False>,

Source§

type Target = T

The Python output type
Source§

type Output = Borrowed<'a, 'py, T>

The smart pointer type to use. Read more
Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn into_pyobject( self, py: Python<'py>, ) -> Result<<PyClassGuardMut<'a, T> as IntoPyObject<'py>>::Output, <PyClassGuardMut<'a, T> as IntoPyObject<'py>>::Error>

Performs the conversion.
Source§

impl<'a, 'py, T> IntoPyObject<'py> for &PyClassGuardMut<'a, T>
where T: PyClass<Frozen = False>,

Source§

type Target = T

The Python output type
Source§

type Output = Borrowed<'a, 'py, T>

The smart pointer type to use. Read more
Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn into_pyobject( self, py: Python<'py>, ) -> Result<<&PyClassGuardMut<'a, T> as IntoPyObject<'py>>::Output, <&PyClassGuardMut<'a, T> as IntoPyObject<'py>>::Error>

Performs the conversion.
Source§

impl<T> Send for PyClassGuardMut<'_, T>
where T: PyClass<Frozen = False> + Send + Sync,

Source§

impl<T> Sync for PyClassGuardMut<'_, T>
where T: PyClass<Frozen = False> + Sync,

Source§

impl<'a, 'py, T> TryFrom<&'a Bound<'py, T>> for PyClassGuardMut<'a, T>
where T: PyClass<Frozen = False>,

Source§

type Error = PyBorrowMutError

The type returned in the event of a conversion error.
Source§

fn try_from( value: &'a Bound<'py, T>, ) -> Result<PyClassGuardMut<'a, T>, <PyClassGuardMut<'a, T> as TryFrom<&'a Bound<'py, T>>>::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl<'a, T> Freeze for PyClassGuardMut<'a, T>

§

impl<'a, T> RefUnwindSafe for PyClassGuardMut<'a, T>
where T: RefUnwindSafe,

§

impl<'a, T> Unpin for PyClassGuardMut<'a, T>

§

impl<'a, T> UnsafeUnpin for PyClassGuardMut<'a, T>

§

impl<'a, T> UnwindSafe for PyClassGuardMut<'a, T>
where T: RefUnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<R> CryptoRng for R
where R: TryCryptoRng<Error = Infallible> + ?Sized,

Source§

impl<T> CryptoRng for T
where T: DerefMut, <T as Deref>::Target: CryptoRng,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<'py, T> IntoPyObjectExt<'py> for T
where T: IntoPyObject<'py>,

Source§

fn into_bound_py_any(self, py: Python<'py>) -> Result<Bound<'py, PyAny>, PyErr>

Converts self into an owned Python object, dropping type information.
Source§

fn into_py_any(self, py: Python<'py>) -> Result<Py<PyAny>, PyErr>

Converts self into an owned Python object, dropping type information and unbinding it from the 'py lifetime.
Source§

fn into_pyobject_or_pyerr(self, py: Python<'py>) -> Result<Self::Output, PyErr>

Converts self into a Python object. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PyErrArguments for T
where T: for<'py> IntoPyObject<'py> + Send + Sync,

Source§

fn arguments(self, py: Python<'_>) -> Py<PyAny>

Arguments for exception
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<R> Rng for R
where R: TryRng<Error = Infallible> + ?Sized,

Source§

fn next_u32(&mut self) -> u32

Return the next random u32.
Source§

fn next_u64(&mut self) -> u64

Return the next random u64.
Source§

fn fill_bytes(&mut self, dst: &mut [u8])

Fill dest with random data. Read more
Source§

impl<R> Rng for R
where R: RngCore + ?Sized,

Source§

fn random<T>(&mut self) -> T

Return a random value via the StandardUniform distribution. Read more
Source§

fn random_iter<T>(self) -> Iter<StandardUniform, Self, T>

Return an iterator over random variates Read more
Source§

fn random_range<T, R>(&mut self, range: R) -> T
where T: SampleUniform, R: SampleRange<T>,

Generate a random value in the given range. Read more
Source§

fn random_bool(&mut self, p: f64) -> bool

Return a bool with a probability p of being true. Read more
Source§

fn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool

Return a bool with a probability of numerator/denominator of being true. Read more
Source§

fn sample<T, D>(&mut self, distr: D) -> T
where D: Distribution<T>,

Sample a new value, using the given distribution. Read more
Source§

fn sample_iter<T, D>(self, distr: D) -> Iter<D, Self, T>
where D: Distribution<T>, Self: Sized,

Create an iterator that generates values using the given distribution. Read more
Source§

fn fill<T>(&mut self, dest: &mut T)
where T: Fill + ?Sized,

Fill any type implementing Fill with random data Read more
Source§

fn gen<T>(&mut self) -> T

👎Deprecated since 0.9.0:

Renamed to random to avoid conflict with the new gen keyword in Rust 2024.

Alias for Rng::random.
Source§

fn gen_range<T, R>(&mut self, range: R) -> T
where T: SampleUniform, R: SampleRange<T>,

👎Deprecated since 0.9.0:

Renamed to random_range

Source§

fn gen_bool(&mut self, p: f64) -> bool

👎Deprecated since 0.9.0:

Renamed to random_bool

Alias for Rng::random_bool.
Source§

fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool

👎Deprecated since 0.9.0:

Renamed to random_ratio

Source§

impl<R> RngCore for R
where R: Rng,

Source§

impl<T> RngCore for T
where T: DerefMut, <T as Deref>::Target: RngCore,

Source§

fn next_u32(&mut self) -> u32

Return the next random u32. Read more
Source§

fn next_u64(&mut self) -> u64

Return the next random u64. Read more
Source§

fn fill_bytes(&mut self, dst: &mut [u8])

Fill dest with random data. Read more
Source§

impl<R> RngExt for R
where R: Rng + ?Sized,

Source§

fn random<T>(&mut self) -> T

Return a random value via the StandardUniform distribution. Read more
Source§

fn random_iter<T>(self) -> Iter<StandardUniform, Self, T>

Return an iterator over random variates Read more
Source§

fn random_range<T, R>(&mut self, range: R) -> T
where T: SampleUniform, R: SampleRange<T>,

Generate a random value in the given range. Read more
Source§

fn random_bool(&mut self, p: f64) -> bool

Return a bool with a probability p of being true. Read more
Source§

fn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool

Return a bool with a probability of numerator/denominator of being true. Read more
Source§

fn sample<T, D>(&mut self, distr: D) -> T
where D: Distribution<T>,

Sample a new value, using the given distribution. Read more
Source§

fn sample_iter<T, D>(self, distr: D) -> Iter<D, Self, T>
where D: Distribution<T>, Self: Sized,

Create an iterator that generates values using the given distribution. Read more
Source§

fn fill<T>(&mut self, dest: &mut [T])
where T: Fill,

Fill any type implementing Fill with random data Read more
Source§

impl<R> TryCryptoRng for R
where R: DerefMut, <R as Deref>::Target: TryCryptoRng,

Source§

impl<R> TryCryptoRng for R
where R: CryptoRng + ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<R> TryRng for R
where R: DerefMut, <R as Deref>::Target: TryRng,

Source§

type Error = <<R as Deref>::Target as TryRng>::Error

The type returned in the event of a RNG error. Read more
Source§

fn try_next_u32(&mut self) -> Result<u32, <R as TryRng>::Error>

Return the next random u32.
Source§

fn try_next_u64(&mut self) -> Result<u64, <R as TryRng>::Error>

Return the next random u64.
Source§

fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), <R as TryRng>::Error>

Fill dst entirely with random data.
Source§

impl<R> TryRngCore for R
where R: TryRng,

Source§

type Error = <R as TryRng>::Error

👎Deprecated since 0.10.0:

use TryRng instead

Error type.
Source§

impl<R> TryRngCore for R
where R: RngCore + ?Sized,

Source§

type Error = Infallible

The type returned in the event of a RNG error.
Source§

fn try_next_u32(&mut self) -> Result<u32, <R as TryRngCore>::Error>

Return the next random u32.
Source§

fn try_next_u64(&mut self) -> Result<u64, <R as TryRngCore>::Error>

Return the next random u64.
Source§

fn try_fill_bytes( &mut self, dst: &mut [u8], ) -> Result<(), <R as TryRngCore>::Error>

Fill dest entirely with random data.
Source§

fn unwrap_err(self) -> UnwrapErr<Self>
where Self: Sized,

Wrap RNG with the UnwrapErr wrapper.
Source§

fn unwrap_mut(&mut self) -> UnwrapMut<'_, Self>

Wrap RNG with the UnwrapMut wrapper.
Source§

fn read_adapter(&mut self) -> RngReadAdapter<'_, Self>
where Self: Sized,

Convert an RngCore to a RngReadAdapter.
Source§

impl<T> Ungil for T
where T: Send,

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V