pyo3

Rust bindings for the Python interpreter

PyO3

Build Status
Actions Status
codecov
crates.io
Join the dev chat

Rust bindings for Python. This includes running and interacting with Python code from a Rust binary, as well as writing native Python modules.

A comparison with rust-cpython can be found in the guide.

Usage

PyO3 supports Python 3.5 and up. The minimum required Rust version is 1.42.0-nightly 2020-01-21.

If you have never used nightly Rust, the official guide has
a great section
about installing it.

PyPy is also supported (via cpyext) for Python 3.5 only, targeted PyPy version is 7.0.0.
Please refer to the guide for installation instruction against PyPy.

You can either write a native Python module in Rust, or use Python from a Rust binary.

However, on some OSs, you need some additional packages. E.g. if you are on Ubuntu 18.04, please run

sudo apt install python3-dev python-dev

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"
crate-type = ["cdylib"]

[dependencies.pyo3]
version = "0.9.0-alpha.1"
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())
}

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

    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",
]

For developing, you can 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 like this:

[dependencies]
pyo3 = "0.9.0-alpha.1"

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

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

fn main() -> Result<(), ()> {
    let gil = Python::acquire_gil();
    let py = gil.python();
    main_(py).map_err(, e, {
        // We can't display python error type via ::std::fmt::Display,
        // so print error here manually.
        e.print_and_set_sys_last_vars(py);
    })
}

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

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

Examples and tooling

  • examples/word-count Counting the occurrences of a word in a text file
  • hyperjson A hyper-fast Python module for reading/writing JSON data using Rust's serde-json
  • rust-numpy Rust binding of NumPy C-API
  • html-py-ever Using html5ever through kuchiki to speed up html parsing and css-selecting.
  • pyo3-built Simple macro to expose metadata obtained with the built crate as a PyDict
  • point-process High level API for pointprocesses as a Python library
  • autopy A simple, cross-platform GUI automation library for Python and Rust.
    • Contains an example of building wheels on TravisCI and appveyor using cibuildwheel
  • orjson Fast Python JSON library
  • inline-python Inline Python code directly in your Rust code
  • Rogue-Gym Customizable rogue-like game for AI experiments
    • Contains an example of building wheels on Azure Pipelines
  • fastuuid Python bindings to Rust's UUID library
  • python-ext-wasm Python library to run WebAssembly binaries
  • dict-derive Derive FromPyObject to automatically transform Python dicts into Rust structs
  • mocpy Astronomical Python library offering data structures for describing any arbitrary coverage regions on the unit sphere
  • tokenizers Python bindings to the Hugging Face tokenizers (NLP) written in Rust

License

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

主要指標

概覽
名稱與所有者robotology/yarp
主編程語言C++
編程語言Rust (語言數: 20)
平台
許可證Other
所有者活动
創建於2013-04-18 09:13:24
推送於2025-05-15 08:36:42
最后一次提交2025-05-15 10:36:42
發布數86
最新版本名稱v3.11.2 (發布於 2025-02-28 12:42:51)
第一版名稱v2.0.4 (發布於 2006-07-05 14:27:32)
用户参与
星數562
關注者數59
派生數200
提交數18.7k
已啟用問題?
問題數1290
打開的問題數239
拉請求數1641
打開的拉請求數22
關閉的拉請求數164
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?