# pyo3 - Rust
Keywords: rust, rustlang, rust-lang, pyo3

# Crate pyo3 [−] [src]

Rust bindings to the Python interpreter.

Look at the guide for a detailed introduction.

# Ownership and Lifetimes

Because all Python objects potentially have multiple owners, the concept of Rust mutability does not apply to Python objects. As a result, PyO3 allows mutating Python objects even if they are not stored in a mutable Rust variable.

In Python, all objects are implicitly reference counted. The Python interpreter uses a global interpreter lock (GIL) to ensure thread-safety. Thus, we use `struct Python<'py>` as a token to indicate that a function can assume that the GIL is held. In Rust, we use different types to represent a reference to a Python object, depending on whether we know the GIL is held, and depending on whether we know the underlying type. See the guide for an explanation of the different Python object types.

A `Python` instance is either obtained explicitly by acquiring the GIL, or implicitly by PyO3 when it generates the wrapper code for Rust functions and structs wrapped as Python functions and objects.

# Error Handling

The vast majority of operations in this library will return `PyResult<...>`. This is an alias for the type `Result<..., PyErr>`.

A `PyErr` represents a Python exception. Errors within the `PyO3` library are also exposed as Python exceptions.

# Example

## Using Rust from Python

PyO3 can be used to generate a native Python module.

`Cargo.toml`

    [package]
    name = "string-sum"
    version = "0.1.0"
    edition = "2018"

    [lib]
    name = "string_sum"
    # "cdylib" is necessary to produce a shared library for Python to import from.
    #
    # Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able
    # to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.:
    # crate-type = ["cdylib", "rlib"]
    crate-type = ["cdylib"]

    [dependencies.pyo3]
    version = "0.13.2"
    features = ["extension-module"]

`src/lib.rs`

    use pyo3::prelude::*;
    use pyo3::wrap_pyfunction;

    #[pyfunction]
    /// Formats the sum of two numbers as string.
    fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
        Ok((a + b).to_string())
    }

    #[pymodule]
    /// A Python module implemented in Rust.
    fn string_sum(py: Python, m: &PyModule) -> PyResult<()> {
        m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;

        Ok(())
    }

On Windows and linux, you can build normally with `cargo build --release`. On macOS, you need to set additional linker arguments. One option is to compile with `cargo rustc --release -- -C link-arg=-undefined -C link-arg=dynamic_lookup`, the other is to create a `.cargo/config` with the following content:

    [target.x86_64-apple-darwin]
    rustflags = [
      "-C", "link-arg=-undefined",
      "-C", "link-arg=dynamic_lookup",
    ]

    [target.aarch64-apple-darwin]
    rustflags = [
      "-C", "link-arg=-undefined",
      "-C", "link-arg=dynamic_lookup",
    ]

While developing, you symlink (or copy) and rename the shared library from the target folder: On macOS, rename `libstring_sum.dylib` to `string_sum.so`, on Windows `libstring_sum.dll` to `string_sum.pyd` and on Linux `libstring_sum.so` to `string_sum.so`. Then open a Python shell in the same folder and you’ll be able to `import string_sum`.

To build, test and publish your crate as a Python module, you can use maturin or setuptools-rust. You can find an example for setuptools-rust in examples/word-count, while maturin should work on your crate without any configuration.

## Using Python from Rust

Add `pyo3` to your `Cargo.toml`:

    [dependencies.pyo3]
    version = "0.13.2"
    features = ["auto-initialize"]

Example program displaying the value of `sys.version`:

    use pyo3::prelude::*;
    use pyo3::types::IntoPyDict;

    fn main() -> PyResult<()> {
        let gil = Python::acquire_gil();
        let py = gil.python();
        let sys = py.import("sys")?;
        let version: String = sys.get("version")?.extract()?;

        let locals = [("os", py.import("os")?)].into_py_dict(py);
        let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
        let user: String = py.eval(code, None, Some(&locals))?.extract()?;

        println!("Hello {}, I'm Python {}", user, version);
        Ok(())
    }

## Re-exports

`pub use crate::class::*;`
`pub use crate::conversion::AsPyPointer;`
`pub use crate::conversion::FromPyObject;`
`pub use crate::conversion::FromPyPointer;`
`pub use crate::conversion::IntoPy;`
`pub use crate::conversion::IntoPyPointer;`
`pub use crate::conversion::PyTryFrom;`
`pub use crate::conversion::PyTryInto;`
`pub use crate::conversion::ToBorrowedObject;`
`pub use crate::conversion::ToPyObject;`
`pub use crate::pycell::PyCell;`
`pub use crate::pycell::PyRef;`
`pub use crate::pycell::PyRefMut;`
`pub use crate::pyclass::PyClass;`
`pub use crate::pyclass_init::PyClassInitializer;`
`pub use crate::type_object::type_flags;`
`pub use crate::type_object::PyTypeInfo;`

## Modules

buffer | `PyBuffer` implementation
class | Python object protocols
conversion | Conversions between various states of Rust and Python types and their wrappers.
exceptions | Exception types defined by Python.
ffi | Raw ffi declarations for the c interface of python
freelist | Free allocation list
marshal | Support for the Python `marshal` format. Not supported in limited API builds.
once_cell |
panic |
prelude | A collection of items you most likely want to have in scope when working with pyo3
proc_macro | The proc macros, which are also part of the prelude.
pycell | Includes `PyCell` implementation.
pyclass | `PyClass` and related traits.
pyclass_init | Initialization utilities for `#[pyclass]`.
pyclass_slots | This module contains additional fields for `#[pyclass]`.. Mainly used by our proc-macro codes.
type_object | Python type object information
types | Various types defined by the Python interpreter such as `int`, `str` and `tuple`.

## Macros

create_exception | Defines a new exception type.
create_exception_type_object | `impl $crate::type_object::PyTypeObject for $name` where `$name` is an exception newly defined in Rust code.
impl_exception_boilerplate | The boilerplate to convert between a Rust type and a Python exception.
import_exception | Defines a Rust type for an exception defined in Python code.
py_run | A convenient macro to execute a Python code snippet, with some local variables set.
pyobject_native_type |
pyobject_native_type_base |
pyobject_native_type_core |
pyobject_native_type_extract |
pyobject_native_type_info |
pyobject_native_type_named |
pyobject_native_type_sized |
pyobject_native_var_type |
raw_pycfunction | Returns the function that is called in the C-FFI.
wrap_pyfunction | Returns a function that takes a Python instance and returns a Python function.
wrap_pymodule | Returns a function that takes a Python instance and returns a Python module.

## Structs

GILGuard | RAII type that represents the Global Interpreter Lock acquisition. To get hold of a value of this type, see `Python::acquire_gil`.
GILPool | A RAII pool which PyO3 uses to store owned Python references.
Py | A Python object of known type T.
PyAny | A Python object with GIL lifetime
PyDowncastError | Error that indicates a failure to convert a PyAny to a more specific Python type.
PyErr | Represents a Python exception that was raised.
Python | Marker type that indicates that the GIL is currently held.
PythonVersionInfo | Represents the major, minor, and patch (if any) versions of this interpreter.

## Traits

PyErrArguments | Helper conversion trait that allows to use custom arguments for lazy exception construction.
PyNativeType | Types that are built into the Python interpreter.

## Functions

prepare_freethreaded_python | Prepares the use of Python in a free-threaded context.
with_embedded_python_interpreter ⚠ | Executes the provided closure with an embedded Python interpreter.

## Type Definitions

PyObject | A commonly-used alias for `Py<PyAny>`.
PyResult | Represents the result of a Python call.