跳转到主要内容

Setuptools Rust 扩展插件

项目描述

Setuptools 插件用于构建 Rust Python 扩展

github actions pypi package readthedocs Ruff

setuptools-rust 是一个 Setuptools 插件,用于构建使用 PyO3rust-cpython 实现的 Rust Python 扩展。

将用Rust编写的Python扩展编译和分发得像用C编写一样简单。

快速入门

以下是一个非常基础的教程,展示了如何在pyproject.toml中使用setuptools-rust。它假设您已经有一系列要分发的Python和Rust文件。您可以在github仓库examples/hello-world目录中查看这些文件的示例。有关如何在Rust中编写Python模块的详细信息,请参阅PyO3文档

hello-world
├── python
│   └── hello_world
│       └── __init__.py
└── rust
    └── lib.rs

一旦实现文件就位,我们需要添加一个pyproject.toml文件,该文件告诉任何想要使用您项目的人如何构建它。在这个文件中,我们使用一个表格数组(TOML术语与Python字典列表等价),用于指定用Rust编写的不同扩展模块

# pyproject.toml
[build-system]
requires = ["setuptools", "setuptools-rust"]
build-backend = "setuptools.build_meta"

[project]
name = "hello-world"
version = "1.0"

[tool.setuptools.packages]
# Pure Python packages/modules
find = { where = ["python"] }

[[tool.setuptools-rust.ext-modules]]
# Private Rust extension module to be nested into the Python package
target = "hello_world._lib"  # The last part of the name (e.g. "_lib") has to match lib.name in Cargo.toml,
                             # but you can add a prefix to nest it inside of a Python package.
path = "Cargo.toml"      # Default value, can be omitted
binding = "PyO3"         # Default value, can be omitted

每个扩展模块应直接映射到Cargo清单文件上的相应[lib]

# Cargo.toml
[package]
name = "hello-world"
version = "0.1.0"
edition = "2021"

[dependencies]
pyo3 = "0.22.0"

[lib]
name = "_lib"  # private module to be nested into Python package,
               # needs to match the name of the function with the `[#pymodule]` attribute
path = "rust/lib.rs"
crate-type = ["cdylib"]  # required for shared library for Python to import from.

# See more keys and their definitions at https://doc.rust-lang.net.cn/cargo/reference/manifest.html
# See also PyO3 docs on writing Cargo.toml files at https://pyo3.rs

您还需要告诉Setuptools,Rust文件是构建您的项目所需的,这可以通过源分发完成。这可以通过MANIFEST.in(见以下示例)或通过如setuptools-scm之类的插件来完成。

# MANIFEST.in
include Cargo.toml
recursive-include rust *.rs

有了这些文件,您就可以在虚拟环境中安装项目以进行测试并确保一切正常工作

# cd hello-world
python3 -m venv .venv
source .venv/bin/activate  # on Linux or macOS
.venv\Scripts\activate     # on Windows
python -m pip install -e .
python
>>> import hello_world
# ... try running something from your new extension module ...
# ... better write some tests with pytest ...

下一步和总结

  • 当您准备好分发项目时,请查看文档中有关构建轮的说明

  • 支持交叉编译,使用crossenvcrosscargo-zigbuild之一。有关示例,请参阅ci.yml中的test-crossenvtest-crosstest-zigbuild Github操作作业。

  • 如果您想分发用Rust编写的二进制可执行文件(而不是Python运行时可以导入的库),也可以使用[[tool.setuptools-rust.bins]](而不是[[tool.setuptools-rust.ext-modules]])。请注意,同时分发库和可执行文件(或多个可执行文件)可能会显着增加由wheel文件分发的包索引的大小,从而增加构建、下载和安装时间。另一种方法是使用Python入口点调用Rust实现(通过PyO3绑定公开)。有关更多见解,请参阅hello-world示例。

  • 有关配置选项的完整参考,请参阅API参考。您可以使用定义在RustExtension类中的任何参数与[[tool.setuptools-rust.ext-modules]]一起使用,以及使用定义在RustBin类中的任何参数与[[tool.setuptools-rust.bins]]一起使用;只需记住在您的pyproject.toml文件中将下划线字符_替换为破折号-即可。

  • Cargo.toml允许每个文件只有一个[lib]表。如果您需要多个扩展模块,您将需要编写多个Cargo.toml文件。或者,您也可以创建一个单独的私有Rust顶层模块,它公开多个子模块(使用PyO3的子模块),这可能会减少构建工件的大小。您始终可以将扩展模块保持为私有,并用纯Python包装它们,以精细控制公共API。

  • 如果想在同一个macOS wheel中包含 [[tool.setuptools-rust.bins]][[tool.setuptools-rust.ext-modules]],可能需要手动添加一个额外的 build.rs 文件。有关此问题的解决方案,请参阅 PyO3/setuptools-rust#351

  • 更多示例请参见

    • hello-world:本教程中使用的代码的更完整版本,它将 [[tool.setuptools-rust.ext-modules]][[tool.setuptools-rust.bins]] 混合在一个单一的分发中。
    • html-py-ever:一个更高级的示例,使用 Rust 包作为依赖项。
    • rust_with_cffi:使用 Rust 和 CFFI
    • namespace_package:将 Rust 编写的模块集成到 PEP 420 命名空间包中。
    • hello-world-script:仅使用 Rust 创建二进制可执行文件,而不是库模块。

项目详情


下载文件

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

源分布

setuptools_rust-1.10.2.tar.gz (309.3 kB 查看散列)

上传时间

构建分布

setuptools_rust-1.10.2-py3-none-any.whl (26.8 kB 查看散列)

上传时间 Python 3

由以下支持