pyo3 README

The project's README from github.com/PyO3/pyo3. As one markdown file: README.md.

PyO3

actions status benchmark codecov crates.io minimum rustc 1.83 discord server 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

Requires Rust 1.83 or greater.

PyO3 supports the following Python distributions:

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 install maturin, use it to generate and build a new Python package, and then launch Python to import and execute a function from the package.

First, follow the commands below to create a new directory containing a new Python virtualenv, and install maturin into the virtualenv using Python's package manager, pip:

# (replace string_sum with the desired package name)
$ mkdir string_sum
$ cd string_sum
$ python -m venv .env
$ source .env/bin/activate
$ pip install maturin

Still inside this string_sum directory, now run maturin init. This will generate the new package source. When given the choice of bindings to use, select pyo3 bindings:

$ maturin init
✔ 🤷 What kind of bindings to use? · pyo3
  ✨ Done! New project created string_sum

The most important files generated by this command are Cargo.toml and lib.rs, which will look roughly like the following:

Cargo.toml

[package]
name = "string_sum"
version = "0.1.0"
edition = "2021"

[lib]
# The name of the native library. This is the name which will be used in Python to import the
# library (i.e. `import string_sum`). If you change this, you must also change the name of the
# `#[pymodule]` in `src/lib.rs`.
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 = "0.29.2"

src/lib.rs

/// A Python module implemented in Rust. The name of this module must match
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
/// import the module.
#[pyo3::pymodule]
mod string_sum {
  use pyo3::prelude::*;

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

Finally, run maturin develop. This will build the package and install it into the Python virtualenv previously created and activated. The package is then ready to be used from python:

$ maturin develop
# lots of progress output as maturin runs the compilation...
$ python
>>> import string_sum
>>> string_sum.sum_as_string(5, 20)
'25'

When checking runtime performance, run maturin develop --release to build with optimizations.

To make changes to the package, just edit the Rust source code and then re-run maturin develop to recompile.

To run this all as a single copy-and-paste, use the bash script below (replace string_sum in the first command with the desired package name):

mkdir string_sum && cd "$_"
python -m venv .env
source .env/bin/activate
pip install maturin
maturin init --bindings pyo3
maturin develop

If you want to be able to run cargo test or use this project in a Cargo workspace and are running into linker issues, there are some workarounds in the FAQ.

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

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:

sudo apt install python3-dev

To install the Python shared library on RPM based distributions (e.g. Fedora, Red Hat, SuSE), install the python3-devel package.

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

[dependencies.pyo3]
version = "0.29.2"
# Enabling this cargo feature will cause PyO3 to start a Python interpreter on first call to `Python::attach`
features = ["auto-initialize"]

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

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

fn main() -> PyResult<()> {
    Python::attach(|py| {
        let sys = py.import("sys")?;
        let version: String = sys.getattr("version")?.extract()?;

        let locals = [("os", py.import("os")?)].into_py_dict(py)?;
        let code = c"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

Articles and other media

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 or the MIT license, at your option.

Python is licensed under the Python License.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusi

pyo3 (PyO3/pyo3)

Searching Database…

16.2K ·GitHub
这是什么?PyO3 是一个提供 Python 解释器绑定的 Rust 库:你可以用它用 Rust 编写原生 Python 扩展模块,也可以把 Python 嵌入到 Rust 程序里,从 Rust 二进制文件中运行 Python 代码。
PyO3 是一个我安装后直接运行的工具,还是一个我写代码时调用的库?是你写代码时调用的东西:它是一个 Rust crate,要添加到 Cargo.toml 里,而最终生成的 Python 包需要用另一个单独的工具来构建,最方便的就是 maturin。
我如何用它构建第一个 Python 扩展模块?先创建一个 Python 虚拟环境,运行 'pip install maturin',然后运行 'maturin init' 并选择 pyo3 绑定。'maturin develop' 会构建这个包并把它安装到虚拟环境里;加上 --release 可以得到优化过的构建版本。
它支持哪些 Rust 和 Python 版本?Rust 需要 1.83 或更高版本。Python 方面:CPython 3.9 或更高版本、PyPy 7.3(Python 3.11+)以及 GraalPy 25.0 或更高版本(Python 3.12+)。
在构建或测试时有什么容易踩的坑吗?运行 'cargo test' 或在 Cargo workspace 里构建时可能遇到链接器问题——FAQ 里记录了解决办法。另外,嵌入 Python 还需要一个带共享库的 Python 构建(Linux 上对应 python3-dev 或 python3-devel)。
PyO3 采用什么许可证?双重许可:你可以任选 Apache-2.0 或 MIT 许可证来使用它,随你喜欢。
我可以反过来在 Rust 里调用 Python 吗?可以——除了扩展 Python,它也支持嵌入 Python。把 pyo3 加进 Cargo.toml,确保你的 Python 安装带有共享库(Ubuntu 上是 python3-dev,RPM 系发行版上是 python3-devel),就能在 Rust 二进制文件里运行 Python 代码并操作 Python 对象。
我必须用 maturin 来构建我的包吗?不必。setuptools-rust 或完全手动配置的方案也可以,而且更灵活,代价是上手时要写更多配置。maturin 只是最省事的路线:配置极少,而且通过 'maturin develop' 能快速重新编译。
有哪些知名的 Python 项目是用 PyO3 构建的?主要是对性能要求高的包:Polars、orjson、pydantic-core、tiktoken、Hugging Face tokenizers 和 cryptography 的 Rust 核心都用了 PyO3。README 里还列出了几十个其他项目,从 rust-numpy 和 pyo3-log 到 Delta Lake、Arrow 以及各种 HTTP 客户端。
Creator
PyO3
Size
63.1 MB
Stars
16.2K
Age
9y
Commits · 90 Days