devela::_dep::pyo3

Struct Python

pub struct Python<'py>(/* private fields */);
Available on crate features dep_pyo3 and std only.
Expand description

A marker token that represents holding the GIL.

It serves three main purposes:

  • It provides a global API for the Python interpreter, such as Python::eval_bound.
  • It can be passed to functions that require a proof of holding the GIL, such as Py::clone_ref.
  • Its lifetime represents the scope of holding the GIL which can be used to create Rust references that are bound to it, such as [Bound<'py, PyAny>].

Note that there are some caveats to using it that you might need to be aware of. See the Deadlocks and Releasing and freeing memory paragraphs for more information about that.

§Obtaining a Python token

The following are the recommended ways to obtain a [Python<'py>] token, in order of preference:

  • If you already have something with a lifetime bound to the GIL, such as [Bound<'py, PyAny>], you can use its .py() method to get a token.
  • In a function or method annotated with #[pyfunction] or #[pymethods] you can declare it as a parameter, and PyO3 will pass in the token when Python code calls it.
  • When you need to acquire the GIL yourself, such as when calling Python code from Rust, you should call Python::with_gil to do that and pass your code as a closure to it.

The first two options are zero-cost; Python::with_gil requires runtime checking and may need to block to acquire the GIL.

§Deadlocks

Note that the GIL can be temporarily released by the Python interpreter during a function call (e.g. importing a module). In general, you don’t need to worry about this because the GIL is reacquired before returning to the Rust code:

`Python` exists   |=====================================|
GIL actually held |==========|         |================|
Rust code running |=======|                |==|  |======|

This behaviour can cause deadlocks when trying to lock a Rust mutex while holding the GIL:

  • Thread 1 acquires the GIL
  • Thread 1 locks a mutex
  • Thread 1 makes a call into the Python interpreter which releases the GIL
  • Thread 2 acquires the GIL
  • Thread 2 tries to locks the mutex, blocks
  • Thread 1’s Python interpreter call blocks trying to reacquire the GIL held by thread 2

To avoid deadlocking, you should release the GIL before trying to lock a mutex or awaiting in asynchronous code, e.g. with Python::allow_threads.

§Releasing and freeing memory

The [Python<'py>] type can be used to create references to variables owned by the Python interpreter, using functions such as Python::eval_bound and PyModule::import.

Implementations§

§

impl Python<'_>

pub fn with_gil<F, R>(f: F) -> R
where F: for<'py> FnOnce(Python<'py>) -> R,

Acquires the global interpreter lock, allowing access to the Python interpreter. The provided closure F will be executed with the acquired Python marker token.

If implementing #[pymethods] or #[pyfunction], declare py: Python as an argument. PyO3 will pass in the token to grant access to the GIL context in which the function is running, avoiding the need to call with_gil.

If the auto-initialize feature is enabled and the Python runtime is not already initialized, this function will initialize it. See prepare_freethreaded_python for details.

If the current thread does not yet have a Python “thread state” associated with it, a new one will be automatically created before F is executed and destroyed after F completes.

§Panics
  • If the auto-initialize feature is not enabled and the Python interpreter is not initialized.
§Examples
use pyo3::prelude::*;
use pyo3::ffi::c_str;

Python::with_gil(|py| -> PyResult<()> {
    let x: i32 = py.eval(c_str!("5"), None, None)?.extract()?;
    assert_eq!(x, 5);
    Ok(())
})

pub unsafe fn with_gil_unchecked<F, R>(f: F) -> R
where F: for<'py> FnOnce(Python<'py>) -> R,

Like Python::with_gil except Python interpreter state checking is skipped.

Normally when the GIL is acquired, we check that the Python interpreter is an appropriate state (e.g. it is fully initialized). This function skips those checks.

§Safety

If Python::with_gil would succeed, it is safe to call this function.

In most cases, you should use Python::with_gil.

A justified scenario for calling this function is during multi-phase interpreter initialization when Python::with_gil would fail before _Py_InitializeMain is called because the interpreter is only partially initialized.

Behavior in other scenarios is not documented.

§

impl<'py> Python<'py>

pub fn allow_threads<T, F>(self, f: F) -> T
where F: Ungil + FnOnce() -> T, T: Ungil,

Temporarily releases the GIL, thus allowing other Python threads to run. The GIL will be reacquired when F’s scope ends.

If you don’t need to touch the Python interpreter for some time and have other Python threads around, this will let you run Rust-only code while letting those other Python threads make progress.

Only types that implement Ungil can cross the closure. See the module level documentation for more information.

If you need to pass Python objects into the closure you can use Py<T>to create a reference independent of the GIL lifetime. However, you cannot do much with those without a Python token, for which you’d need to reacquire the GIL.

§Example: Releasing the GIL while running a computation in Rust-only code
use pyo3::prelude::*;

#[pyfunction]
fn sum_numbers(py: Python<'_>, numbers: Vec<u32>) -> PyResult<u32> {
    // We release the GIL here so any other Python threads get a chance to run.
    py.allow_threads(move || {
        // An example of an "expensive" Rust calculation
        let sum = numbers.iter().sum();

        Ok(sum)
    })
}

Please see the Parallelism chapter of the guide for a thorough discussion of using Python::allow_threads in this manner.

§Example: Passing borrowed Python references into the closure is not allowed
use pyo3::prelude::*;
use pyo3::types::PyString;

fn parallel_print(py: Python<'_>) {
    let s = PyString::new_bound(py, "This object cannot be accessed without holding the GIL >_<");
    py.allow_threads(move || {
        println!("{:?}", s); // This causes a compile error.
    });
}

pub fn eval( self, code: &CStr, globals: Option<&Bound<'py, PyDict>>, locals: Option<&Bound<'py, PyDict>>, ) -> Result<Bound<'py, PyAny>, PyErr>

Evaluates a Python expression in the given context and returns the result.

If globals is None, it defaults to Python module __main__. If locals is None, it defaults to the value of globals.

If globals doesn’t contain __builtins__, default __builtins__ will be added automatically.

§Examples
let result = py.eval(c_str!("[i * 10 for i in range(5)]"), None, None).unwrap();
let res: Vec<i64> = result.extract().unwrap();
assert_eq!(res, vec![0, 10, 20, 30, 40])

pub fn eval_bound( self, code: &str, globals: Option<&Bound<'py, PyDict>>, locals: Option<&Bound<'py, PyDict>>, ) -> Result<Bound<'py, PyAny>, PyErr>

👎Deprecated since 0.23.0: renamed to Python::eval

Deprecated name for Python::eval.

pub fn run( self, code: &CStr, globals: Option<&Bound<'py, PyDict>>, locals: Option<&Bound<'py, PyDict>>, ) -> Result<(), PyErr>

Executes one or more Python statements in the given context.

If globals is None, it defaults to Python module __main__. If locals is None, it defaults to the value of globals.

If globals doesn’t contain __builtins__, default __builtins__ will be added automatically.

§Examples
use pyo3::{
    prelude::*,
    types::{PyBytes, PyDict},
    ffi::c_str,
};
Python::with_gil(|py| {
    let locals = PyDict::new(py);
    py.run(c_str!(
        r#"
import base64
s = 'Hello Rust!'
ret = base64.b64encode(s.encode('utf-8'))
"#),
        None,
        Some(&locals),
    )
    .unwrap();
    let ret = locals.get_item("ret").unwrap().unwrap();
    let b64 = ret.downcast::<PyBytes>().unwrap();
    assert_eq!(b64.as_bytes(), b"SGVsbG8gUnVzdCE=");
});

You can use py_run! for a handy alternative of run if you don’t need globals and unwrapping is OK.

pub fn run_bound( self, code: &str, globals: Option<&Bound<'py, PyDict>>, locals: Option<&Bound<'py, PyDict>>, ) -> Result<(), PyErr>

👎Deprecated since 0.23.0: renamed to Python::run

Deprecated name for Python::run.

pub fn get_type<T>(self) -> Bound<'py, PyType>
where T: PyTypeInfo,

Gets the Python type object for type T.

pub fn get_type_bound<T>(self) -> Bound<'py, PyType>
where T: PyTypeInfo,

👎Deprecated since 0.23.0: renamed to Python::get_type

Deprecated name for Python::get_type.

pub fn import<N>(self, name: N) -> Result<Bound<'py, PyModule>, PyErr>
where N: IntoPyObject<'py, Target = PyString>,

Imports the Python module with the specified name.

pub fn import_bound<N>(self, name: N) -> Result<Bound<'py, PyModule>, PyErr>
where N: IntoPy<Py<PyString>>,

👎Deprecated since 0.23.0: renamed to Python::import

Deprecated name for Python::import.

pub fn None(self) -> Py<PyAny>

Gets the Python builtin value None.

pub fn Ellipsis(self) -> Py<PyAny>

Gets the Python builtin value Ellipsis, or ....

pub fn NotImplemented(self) -> Py<PyAny>

Gets the Python builtin value NotImplemented.

pub fn version(self) -> &'py str

Gets the running Python interpreter version as a string.

§Examples
Python::with_gil(|py| {
    // The full string could be, for example:
    // "3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)]"
    assert!(py.version().starts_with("3."));
});

pub fn version_info(self) -> PythonVersionInfo<'py>

Gets the running Python interpreter version as a struct similar to sys.version_info.

§Examples
Python::with_gil(|py| {
    // PyO3 supports Python 3.7 and up.
    assert!(py.version_info() >= (3, 7));
    assert!(py.version_info() >= (3, 7, 0));
});

pub fn check_signals(self) -> Result<(), PyErr>

Lets the Python interpreter check and handle any pending signals. This will invoke the corresponding signal handlers registered in Python (if any).

Returns Err([PyErr]) if any signal handler raises an exception.

These signals include SIGINT (normally raised by CTRL + C), which by default raises KeyboardInterrupt. For this reason it is good practice to call this function regularly as part of long-running Rust functions so that users can cancel it.

§Example
use pyo3::prelude::*;

#[pyfunction]
fn loop_forever(py: Python<'_>) -> PyResult<()> {
    loop {
        // As this loop is infinite it should check for signals every once in a while.
        // Using `?` causes any `PyErr` (potentially containing `KeyboardInterrupt`)
        // to break out of the loop.
        py.check_signals()?;

        // do work here
    }
}
§Note

This function calls PyErr_CheckSignals() which in turn may call signal handlers. As Python’s signal API allows users to define custom signal handlers, calling this function allows arbitrary Python code inside signal handlers to run.

If the function is called from a non-main thread, or under a non-main Python interpreter, it does nothing yet still returns Ok(()).

§

impl<'unbound> Python<'unbound>

pub unsafe fn assume_gil_acquired() -> Python<'unbound>

Unsafely creates a Python token with an unbounded lifetime.

Many of PyO3 APIs use Python<'_> as proof that the GIL is held, but this function can be used to call them unsafely.

§Safety
  • This token and any borrowed Python references derived from it can only be safely used whilst the currently executing thread is actually holding the GIL.
  • This function creates a token with an unbounded lifetime. Safe code can assume that holding a Python<'py> token means the GIL is and stays acquired for the lifetime 'py. If you let it or borrowed Python references escape to safe code you are responsible for bounding the lifetime 'unbound appropriately. For more on unbounded lifetimes, see the nomicon.

Trait Implementations§

§

impl<'py> Clone for Python<'py>

§

fn clone(&self) -> Python<'py>

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl<'py> Copy for Python<'py>

Auto Trait Implementations§

§

impl<'py> Freeze for Python<'py>

§

impl<'py> RefUnwindSafe for Python<'py>

§

impl<'py> !Send for Python<'py>

§

impl<'py> !Sync for Python<'py>

§

impl<'py> Unpin for Python<'py>

§

impl<'py> UnwindSafe for Python<'py>

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
§

impl<T> ArchivePointee for T

§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
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<T> ByteSized for T

Source§

const BYTE_ALIGN: usize = _

The alignment of this type in bytes.
Source§

const BYTE_SIZE: usize = _

The size of this type in bytes.
Source§

fn byte_align(&self) -> usize

Returns the alignment of this type in bytes.
Source§

fn byte_size(&self) -> usize

Returns the size of this type in bytes. Read more
Source§

fn ptr_size_ratio(&self) -> [usize; 2]

Returns the size ratio between Ptr::BYTES and BYTE_SIZE. Read more
Source§

impl<T, R> Chain<R> for T
where T: ?Sized,

Source§

fn chain<F>(self, f: F) -> R
where F: FnOnce(Self) -> R, Self: Sized,

Chain a function which takes the parameter by value.
Source§

fn chain_ref<F>(&self, f: F) -> R
where F: FnOnce(&Self) -> R,

Chain a function which takes the parameter by shared reference.
Source§

fn chain_mut<F>(&mut self, f: F) -> R
where F: FnOnce(&mut Self) -> R,

Chain a function which takes the parameter by exclusive reference.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

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

Source§

fn type_id() -> TypeId

Returns the TypeId of Self. Read more
Source§

fn type_of(&self) -> TypeId

Returns the TypeId of self. Read more
Source§

fn type_name(&self) -> &'static str

Returns the type name of self. Read more
Source§

fn type_is<T: 'static>(&self) -> bool

Returns true if Self is of type T. Read more
Source§

fn as_any_ref(&self) -> &dyn Any
where Self: Sized,

Upcasts &self as &dyn Any. Read more
Source§

fn as_any_mut(&mut self) -> &mut dyn Any
where Self: Sized,

Upcasts &mut self as &mut dyn Any. Read more
Source§

fn as_any_box(self: Box<Self>) -> Box<dyn Any>
where Self: Sized,

Upcasts Box<self> as Box<dyn Any>. Read more
Source§

fn downcast_ref<T: 'static>(&self) -> Option<&T>

Available on crate feature unsafe_layout only.
Returns some shared reference to the inner value if it is of type T. Read more
Source§

fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T>

Available on crate feature unsafe_layout only.
Returns some exclusive reference to the inner value if it is of type T. Read more
Source§

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

Source§

const NEEDS_DROP: bool = _

Know whether dropping values of this type matters, in compile-time.
Source§

fn mem_align_of<T>() -> usize

Returns the minimum alignment of the type in bytes. Read more
Source§

fn mem_align_of_val(&self) -> usize

Returns the alignment of the pointed-to value in bytes. Read more
Source§

fn mem_size_of<T>() -> usize

Returns the size of a type in bytes. Read more
Source§

fn mem_size_of_val(&self) -> usize

Returns the size of the pointed-to value in bytes. Read more
Source§

fn mem_copy(&self) -> Self
where Self: Copy,

Bitwise-copies a value. Read more
Source§

fn mem_needs_drop(&self) -> bool

Returns true if dropping values of this type matters. Read more
Source§

fn mem_drop(self)
where Self: Sized,

Drops self by running its destructor. Read more
Source§

fn mem_forget(self)
where Self: Sized,

Forgets about self without running its destructor. Read more
Source§

fn mem_replace(&mut self, other: Self) -> Self
where Self: Sized,

Replaces self with other, returning the previous value of self. Read more
Source§

fn mem_take(&mut self) -> Self
where Self: Default,

Replaces self with its default value, returning the previous value of self. Read more
Source§

fn mem_swap(&mut self, other: &mut Self)
where Self: Sized,

Swaps the value of self and other without deinitializing either one. Read more
Source§

unsafe fn mem_zeroed<T>() -> T

Available on crate feature unsafe_layout only.
Returns the value of type T represented by the all-zero byte-pattern. Read more
Source§

unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst

Available on crate feature unsafe_layout only.
Returns the value of type T represented by the all-zero byte-pattern. Read more
Source§

fn mem_as_bytes(&self) -> &[u8]
where Self: Sync + Unpin,

Available on crate feature unsafe_slice only.
View a Sync + Unpin self as &[u8]. Read more
Source§

fn mem_as_bytes_mut(&mut self) -> &mut [u8]
where Self: Sync + Unpin,

Available on crate feature unsafe_slice only.
View a Sync + Unpin self as &mut [u8]. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<S> FromSample<S> for S

§

fn from_sample_(s: S) -> S

Source§

impl<T> Hook for T

Source§

fn hook_ref<F>(self, f: F) -> Self
where F: FnOnce(&Self),

Applies a function which takes the parameter by shared reference, and then returns the (possibly) modified owned value. Read more
Source§

fn hook_mut<F>(self, f: F) -> Self
where F: FnOnce(&mut Self),

Applies a function which takes the parameter by exclusive reference, and then returns the (possibly) modified owned value. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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
§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

§

fn into_sample(self) -> T

§

impl<T> LayoutRaw for T

§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Returns the layout of the type.
§

impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
where T: SharedNiching<N1, N2>, N1: Niching<T>, N2: Niching<T>,

§

unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool

Returns whether the given value has been niched. Read more
§

fn resolve_niched(out: Place<NichedOption<T, N1>>)

Writes data to out indicating that a T is niched.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

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

Initializes a with the given initializer. Read more
§

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

Dereferences the given pointer. Read more
§

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

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

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

impl<T> Pointee for T

§

type Metadata = ()

The metadata type for pointers and references to this type.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

§

fn to_sample_(self) -> U

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.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,