跳转到主要内容

使用pyo3、cffi和uniffi绑定构建和发布crate以及作为Python包的二进制Rust程序

项目描述

matu-rin

以前称为pyo3-pack

Maturin User Guide Crates.io PyPI Actions Status FreeBSD discord server

使用pyo3、cffi和uniffi绑定以及rust二进制文件,将crate构建和发布为Python包,配置简单。它支持在Windows、Linux、mac和FreeBSD上构建Python 3.8+的wheel包,可以上传到PyPI,并具备基本的pypy和graalpy支持。

查看用户指南

使用方法

您可以从最新版本发布中下载二进制文件,或者使用pipx进行安装。

pipx install maturin

[!注意]

如果不使用pipx,则也可以使用pip install maturin

有四个主要命令

  • maturin new创建一个新的带有maturin配置的Cargo项目。
  • maturin publish将crate构建成Python包并发布到PyPI。
  • maturin build构建wheel包并将其存储在文件夹中(默认为target/wheels),但不会上传。可以使用twinematurin upload上传。
  • maturin develop构建crate并将其作为Python模块直接安装到当前的虚拟环境中。请注意,尽管maturin develop更快,但它不支持在maturin build之后运行pip install的所有功能。

pyo3绑定将自动检测。对于cffi或二进制文件,需要传递-b cffi-b bin。maturin不需要额外的配置文件,也不会与现有的setuptools-rust或milksnake配置冲突。您甚至可以将其与测试工具(如tox)集成。在test-crates文件夹中有不同绑定的示例。

包的名称将是Cargo项目的名称,即Cargo.toml[package]部分的名称字段。您在导入时使用的模块名称将是[lib]部分的name值(默认为包的名称)。对于二进制文件,它是cargo生成的二进制文件名称。

在执行maturin buildmaturin develop命令时,可以通过添加-r--release标志来编译性能优化的程序。

Python打包基础

Python包有两种格式:一种是构建形式,称为wheel,另一种是源分布(sdist),两者都是归档。wheel可以与任何Python版本、解释器(主要是cpython和pypy)、操作系统和硬件架构兼容(对于纯Python wheel),可以限制在特定平台和架构上(例如,使用ctypes或cffi时),或限制在特定架构和操作系统上的特定Python解释器和版本(例如,使用pyo3)。

使用pip install安装包时,pip会尝试找到匹配的wheel并安装。如果没有找到,它将下载源分布并为当前平台构建一个wheel,这需要安装正确的编译器。安装wheel比安装源分布要快得多,因为构建wheel通常很慢。

当您发布一个可以通过pip install安装的包时,您需要将其上传到PyPI,这是官方的包仓库。对于测试,可以使用测试PyPI,您可以使用pip install --index-url https://test.pypi.org/simple/来使用它。请注意,对于Linux发布,您需要使用manylinux docker容器,而对于从您的仓库发布,您可以使用PyO3/maturin-action github动作

pyo3

对于pyo3,maturin只能为已安装的Python版本构建软件包。在Linux和mac上,将使用PATH中的所有Python版本。如果您没有使用-i设置自己的解释器,将使用启发式方法来搜索Python安装。在Windows上,将使用Python启动器(由python.org安装程序默认安装)的所有版本以及除base之外的所有conda环境。您可以使用list-python子命令来检查哪些版本被选中。

pyo3将在环境变量PYTHON_SYS_EXECUTABLE中设置使用的Python解释器,这可以在自定义构建脚本中使用。即使只在Linux上测试了pypy3.7-7.3,maturin也可以使用pyo3为pypy构建和上传wheels。

Cffi

Cffi wheels与所有Python版本兼容,包括pypy。如果cffi未安装且Python在virtualenv内部运行,maturin将安装它;否则,您必须自己安装它(pip install cffi)。

maturin使用cbindgen生成一个头文件,可以通过在项目根目录中配置cbindgen.toml文件来自定义cbindgen。或者,您可以使用一个构建脚本,将头文件写入到$PROJECT_ROOT/target/header.h

基于头文件,maturin生成一个模块,它导出一个ffi和一个lib对象。

自定义构建脚本示例
use cbindgen;
use std::env;
use std::path::Path;

fn main() {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

    let bindings = cbindgen::Builder::new()
        .with_no_includes()
        .with_language(cbindgen::Language::C)
        .with_crate(crate_dir)
        .generate()
        .unwrap();
    bindings.write_to_file(Path::new("target").join("header.h"));
}

uniffi

uniffi绑定使用uniffi-rs从接口定义文件生成Python ctypes绑定。uniffi wheels与所有Python版本兼容,包括pypy。

混合Rust/Python项目

要创建混合Rust/Python项目,在Cargo.toml旁边的文件夹中创建一个以您的模块名称命名的文件夹(例如,在Cargo.toml中的lib.name)并添加您的Python源代码。

my-project
├── Cargo.toml
├── my_project
│   ├── __init__.py
│   └── bar.py
├── pyproject.toml
├── README.md
└── src
    └── lib.rs

您可以在pyproject.toml中通过设置tool.maturin.python-source来指定不同的Python源目录,例如

pyproject.toml

[tool.maturin]
python-source = "python"
module-name = "my_project._lib_name"

然后,项目结构将如下所示

my-project
├── Cargo.toml
├── python
│   └── my_project
│       ├── __init__.py
│       └── bar.py
├── pyproject.toml
├── README.md
└── src
    └── lib.rs

[!注意]

建议使用此结构以避免常见的ImportError陷阱

maturin将原生扩展作为Python文件夹中的一个模块添加。当使用develop时,maturin将复制原生库和cffi的粘合代码到您的Python文件夹。您应该将这些文件添加到您的gitignore中。

使用cffi,您可以使用from .my_project import lib然后使用lib.my_native_function;使用pyo3,您可以直接使用from .my_project import my_native_function

maturin develop后pyo3的示例布局

my-project
├── Cargo.toml
├── my_project
│   ├── __init__.py
│   ├── bar.py
│   └── _lib_name.cpython-36m-x86_64-linux-gnu.so
├── README.md
└── src
    └── lib.rs

在此过程中,请确保在您的代码中将模块名称设置为与module-name的最后部分匹配(不要包含包路径)

#[pymodule]
#[pyo3(name="_lib_name")]
fn my_lib_name(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    m.add_class::<MyPythonRustClass>()?;
    Ok(())
}

Python元数据

maturin支持PEP 621,您可以在pyproject.toml中指定Python包元数据。maturin将合并来自Cargo.tomlpyproject.toml的元数据,pyproject.toml优先于Cargo.toml

要指定Python依赖项,请在pyproject.toml[project]部分中添加一个名为dependencies的列表。此列表与setuptools中的install_requires等效。

[project]
name = "my-project"
dependencies = ["flask~=1.1.0", "toml==0.10.0"]

Pip允许添加所谓的控制台脚本,它们是执行程序中某些函数的shell命令。您可以在[project.scripts]部分中添加控制台脚本。键是脚本名称,而值是以some.module.path:class.function格式的函数路径,其中class部分是可选的。该函数没有参数调用。示例

[project.scripts]
get_42 = "my_project:DummyClass.get_42"

您还可以在pyproject.toml中的project.classifiers下指定trove分类器

[project]
name = "my-project"
classifiers = ["Programming Language :: Python"]

源分布

maturin支持通过pyproject.toml进行构建。要使用它,在Cargo.toml旁边创建一个pyproject.toml,内容如下

[build-system]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"

如果存在带有 [build-system] 条目的 pyproject.toml,当指定了 --sdist 选项时,maturin 可以构建您包的源分布。源分布将包含与 cargo package 相同的文件。要仅构建源分布,请传递不带任何值的 --interpreter

例如,您可以使用 pip install . 安装您的包。使用 pip install . -v 可以查看 cargo 和 maturin 的输出。

您可以使用 compatibilityskip-auditwheelbindingsstrip 以及在 [tool.maturin] 下的常见 Cargo 构建选项(如 features),就像直接运行 maturin 一样。对于 cffi 和 bin 项目,需要 bindings 键,因为这些无法自动检测。目前,所有构建都在发布模式下进行(有关详细信息,请参阅 此线程)。

对于带有 cffi 绑定的非 manylinux 构建,可以使用以下内容

[build-system]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"

[tool.maturin]
bindings = "cffi"
compatibility = "linux"

manylinux 选项也接受为 compatibility 的别名,以向后兼容旧版本的 maturin。

要将在编译期间使用的任意文件包含在 sdist 中,请指定 include 为一个包含 path globs 的数组,并将 format 设置为 sdist

[tool.maturin]
include = [{ path = "path/**/*", format = "sdist" }]

存在一个 maturin sdist 命令,仅用于构建源分布,作为对 pypa/pip#6041 的解决方案。

Manylinux 和 auditwheel

出于可移植性的原因,Linux 上的原生 Python 模块必须仅动态链接一组非常少的库,这些库基本上在所有地方都安装了,因此得名 manylinux。pypa 提供特殊的 Docker 镜像和名为 auditwheel 的工具,以确保符合 manylinux 规则。如果您想发布广泛使用的 Linux PyPI 轮子,您需要使用 manylinux Docker 镜像

Rust 编译器从版本 1.64 开始 需要至少 glibc 2.17,因此您需要使用至少 manylinux2014。对于发布,我们建议使用与具有 manylinux 标志的镜像相同的 manylinux 版本,例如,如果您在 quay.io/pypa/manylinux2014_x86_64 上构建,请使用 --manylinux 2014。如果设置例如 manylinux: 2014PyO3/maturin-action github 动作已自动处理此问题。

maturin 包含 auditwheel 的重实现,自动检查生成的库,并为轮子分配正确的平台标签。如果您的系统 glibc 过新或链接其他共享库,它将分配 linux 标签。您还可以手动禁用这些检查,并直接使用带有 --manylinux off 的原生 Linux 目标。

为了完全符合 manylinux,您需要在 CentOS Docker 容器中编译。基于 manylinux2014 的 pyo3/maturin 镜像将参数传递给 maturin 二进制文件。您可以像这样使用它

docker run --rm -v $(pwd):/io ghcr.io/pyo3/maturin build --release  # or other maturin arguments

请注意,此镜像非常基础,仅包含 python、maturin 和稳定的 rust。如果您需要其他工具,可以在 manylinux 容器内部运行命令。有关示例,请参阅 konstin/complex-manylinux-maturin-docker 或用于实际设置的 nanoporetech/fast-ctc-decode

maturin 本身当为 musl 目标编译时符合 manylinux。

示例

  • ballista-python - 一个绑定到 Apache Arrow 分布式查询引擎 Ballista 的 Python 库
  • bleuscore - 一个纯 Rust 编写的 BLEU 分数计算库
  • chardetng-py - chardetng字符编码检测器的Python绑定。
  • connector-x - ConnectorX使您能够以最快和最节省内存的方式将数据从数据库加载到Python中。
  • datafusion-python - 一个Python库,它将Apache Arrow内存查询引擎DataFusion绑定。
  • deltalake-python - 基于delta-rs且具有Pandas集成的原生Delta Lake Python绑定。
  • opendal - OpenDAL Python绑定,可自由访问数据。
  • orjson - Python的一个快速、正确的JSON库。
  • polars - 基于 Rust、Python 和 Node.js 的快速多线程 DataFrame 库。
  • pydantic-core - pydantic的核心验证逻辑,用 Rust 编写。
  • pyrus-cramjam - 对 Rust 中解/压缩算法的薄 Python 包装。
  • pyxel - 一个专为 Python 设计的复古游戏引擎。
  • roapi - ROAPI可以在不要求您编写任何代码的情况下自动为静态数据集启动只读API。
  • robyn - 一个具有 Rust 运行时的快速且可扩展的异步 Python Web 服务器。
  • ruff - 一个用 Rust 编写的极快 Python 检查器。
  • tantivy-py - Tantivy 的 Python 绑定。
  • watchfiles - 简单、现代且性能高效的 Python 文件监视和代码重载。
  • wonnx - 100% 用 Rust 编写的 GPU 加速 ONNX 推理运行时。

贡献

每个人都欢迎为 maturin 贡献!有很多方式可以支持这个项目,例如

  • 帮助 GitHub 和 Gitter 上的 maturin 用户处理问题
  • 改进文档
  • 编写功能和错误修复
  • 发布有关如何使用 maturin 的博客和示例

我们的 贡献笔记 提供了更多资源,如果您想为 maturin 贡献时间并寻找起点。

如果您没有时间亲自贡献,但仍然希望支持项目的未来成功,我们的一些维护者有 GitHub 赞助页面

许可证

根据以下任一许可发布

任选其一。

项目详细信息


发布历史 发布通知 | RSS 源

下载文件

下载适合您平台的文件。如果您不确定选择哪一个,请了解更多关于安装包的信息。

源代码分发

maturin-1.7.4.tar.gz (191.1 kB 查看哈希值)

上传时间 源代码

构建分发

maturin-1.7.4-py3-none-win_arm64.whl (6.4 MB 查看哈希值)

上传时间 Python 3 Windows ARM64

maturin-1.7.4-py3-none-win_amd64.whl (7.4 MB 查看哈希值)

上传时间 Python 3 Windows x86-64

maturin-1.7.4-py3-none-win32.whl (6.6 MB 查看哈希值)

上传时间 Python 3 Windows x86

maturin-1.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl (10.1 MB 查看哈希值)

上传时间 Python 3 manylinux: glibc 2.17+ s390x

maturin-1.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl (8.7 MB 查看哈希值)

上传时间 Python 3 manylinux: glibc 2.17+ ppc64le musllinux: musl 1.1+ ppc64le

maturin-1.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl (8.1 MB 查看哈希值)

上传时间 Python 3 manylinux: glibc 2.17+ ARMv7l musllinux: musl 1.1+ ARMv7l

maturin-1.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl (8.4 MB 查看哈希值)

上传时间 Python 3 manylinux: glibc 2.17+ ARM64 musllinux: musl 1.1+ ARM64

maturin-1.7.4-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl (8.9 MB 查看哈希值)

上传时间 Python 3 manylinux: glibc 2.12+ x86-64 musllinux: musl 1.1+ x86-64

maturin-1.7.4-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl (8.6 MB 查看哈希值)

上传时间 Python 3 manylinux: glibc 2.12+ i686 musllinux: musl 1.1+ i686

maturin-1.7.4-py3-none-macosx_10_12_x86_64.whl (8.2 MB 查看哈希值)

上传时间 Python 3 macOS 10.12+ x86-64

maturin-1.7.4-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (15.9 MB 查看哈希值)

上传时间 Python 3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64

maturin-1.7.4-py3-none-linux_armv6l.whl (8.2 MB 查看哈希值)

上传时间 Python 3

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面