setuptools-rust
setuptools-rust is a setuptools extension plugin that simplifies the integration of Rust code compilation and packaging into Python projects, especially those leveraging PyO3. It handles the build process for Rust extensions, making it easier to distribute Python packages with native Rust components. The library is actively maintained, currently at version 1.12.1, with a regular release cadence to support new Python and Rust features.
Warnings
- breaking Python 3.8 support was dropped in setuptools-rust v1.11.0. Projects requiring 3.8 or older will fail to build with newer versions.
- deprecated The `py_limited_api` option for `RustExtension` was deprecated in v1.9.0. It's now recommended to let `setuptools-rust` automatically configure this based on `bdist_wheel` settings.
- gotcha The Rust compiler (`rustc`) and Cargo build system must be installed and accessible in your system's PATH for `setuptools-rust` to function.
- gotcha When building in a virtual environment, switching between environments might trigger unnecessary recompilations of Rust extensions.
- gotcha Editable installs (`pip install -e .`) may default to release mode builds, making debugging more difficult.
Install
-
pip install setuptools-rust
Imports
- RustExtension
from setuptools_rust import RustExtension
Quickstart
from setuptools import setup
from setuptools_rust import RustExtension
setup(
name='my_rust_package',
version='0.1.0',
rust_extensions=[
RustExtension(
'my_rust_package.my_module',
'./Cargo.toml',
# debug=True, # Uncomment for debug builds
# features=['some_feature'], # Optional Cargo features
)
],
packages=['my_rust_package'],
)
# To make this example runnable, ensure the following files exist:
#
# pyproject.toml:
# [build-system]
# requires = ["setuptools>=61.0.0", "setuptools-rust>=1.0.0", "wheel"]
# build-backend = "setuptools.build_meta"
#
# Cargo.toml (at the project root, or specified path './Cargo.toml'):
# [package]
# name = "my_module"
# version = "0.1.0"
# edition = "2021"
#
# [lib]
# name = "my_module"
# crate-type = ["cdylib"]
#
# [dependencies]
# pyo3 = { version = "0.21.2", features = ["extension-module"] }
#
# my_rust_package/__init__.py (empty or `from .my_module import *`):
#
# src/lib.rs (for the Rust extension):
# use pyo3::prelude::*;
#
# #[pyfunction]
# fn greet(name: &str) -> PyResult<String> {
# Ok(format!("Hello, {} from Rust!", name))
# }
#
# #[pymodule]
# fn my_module(_py: Python, m: &PyModule) -> PyResult<()> {
# m.add_function(wrap_pyfunction!(greet, m)?)?;
# Ok(())
# }