PyO3

actions status benchmark codecov crates.io minimum rustc 1.41 dev chat contributing notes

Rust bindings for Python, including tools for creating native Python extension modules. Running and interacting with Python code from a Rust binary is also supported.

Usage

PyO3 supports the following software versions: - Python 3.6 and up (CPython and PyPy) - Rust 1.41 and up

You can use PyO3 to write a native Python module in Rust, or to embed Python in a Rust binary. The following sections explain each of these in turn.

Using Rust from Python

PyO3 can be used to generate a native Python module. The easiest way to try this out for the first time is to use maturin. maturin is a tool for building and publishing Rust-based Python packages with minimal configuration. The following steps set up some files for an example Python module, install maturin, and then show how build and import the Python module.

First, create a new folder (let's call it string_sum) containing the following two files:

Cargo.toml

```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.14.2" features = ["extension-module"] ```

src/lib.rs

```rust use pyo3::prelude::*;

/// Formats the sum of two numbers as string.

[pyfunction]

fn sumasstring(a: usize, b: usize) -> PyResult { Ok((a + b).to_string()) }

/// A Python module implemented in Rust. The name of this function must match /// the lib.name setting in the Cargo.toml, else Python will not be able to /// import the module.

[pymodule]

fn stringsum(py: Python, m: &PyModule) -> PyResult<()> { m.addfunction(wrappyfunction!(sumasstring, m)?)?;

Ok(())

} ```

With those two files in place, now maturin needs to be installed. This can be done using Python's package manager pip. First, load up a new Python virtualenv, and install maturin into it:

bash $ cd string_sum $ python -m venv .env $ source .env/bin/activate $ pip install maturin

Now build and execute the module:

```bash $ maturin develop

lots of progress output as maturin runs the compilation...

$ python

import stringsum stringsum.sumasstring(5, 20) '25' ```

As well as with maturin, it is possible to build using setuptools-rust or manually. Both offer more flexibility than maturin but require further configuration.

Using Python from Rust

To embed Python into a Rust binary, you need to ensure that your Python installation contains a shared library. The following steps demonstrate how to ensure this (for Ubuntu), and then give some example code which runs an embedded Python interpreter.

To install the Python shared library on Ubuntu:

bash sudo apt install python3-dev

Start a new project with cargo new and add pyo3 to the Cargo.toml like this:

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

Example program displaying the value of sys.version and the current user name:

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

fn main() -> PyResult<()> { Python::with_gil(|py| { 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(())
})

} ```

The guide has a section with lots of examples about this topic.

Tools and libraries

Examples

Contributing

Everyone is welcomed to contribute to PyO3! There are many ways to support the project, such as:

Our contributing notes and architecture guide have more resources if you wish to volunteer time for PyO3 and are searching where to start.

If you don't have time to contribute yourself but still wish to support the project's future success, some of our maintainers have Github sponsorship pages:

License

PyO3 is licensed under the Apache-2.0 license. Python is licensed under the Python License.