single |
# Setuptools plugin for Rust extensions
[github actions]
[pypi package]
[readthedocs]
[Ruff]
`setuptools-rust` is a plugin for `setuptools` to build Rust Python
extensions implemented with [PyO3] or [rust-cpython].
Compile and distribute Python extensions written in Rust as easily as if
they were written in C.
## Quickstart
The following is a very basic tutorial that shows how to use
`setuptools-rust` in `pyproject.toml`.
It assumes that you already have a bunch of Python and Rust files that you
want
to distribute. You can see examples for these files in the
[`examples/hello-world`]
directory in the [github repository].
The [PyO3 docs] have detailed information on how to write Python
modules in Rust.
```
hello-world
├── python
│ └── hello_world
│ └── __init__.py
└── rust
└── lib.rs
```
Once the implementation files are in place, we need to add a
`pyproject.toml`
file that tells anyone that wants to use your project how to build it.
In this file, we use an [array of tables]
(TOML jargon equivalent to Python's list of dicts) for
``[[tool.setuptools-rust.ext-modules]]``,
to specify different extension modules written in Rust:
```toml
# 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
```
Each extension module should map directly into the corresponding `[lib]`
table on the
[Cargo manifest file]:
```toml
# 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.org/cargo/reference/manifest.html
# See also PyO3 docs on writing Cargo.toml files at https://pyo3.rs
```
You will also need to tell Setuptools that the Rust files are required to
build your
project from the [source distribution].
That can be done either via `MANIFEST.in` (see example below) or via a
plugin like
[`setuptools-scm`].
|