PyO3 + Maturin Python Bindings
Project Structure
my-rust-lib/
├── Cargo.toml # [lib] crate-type = ["cdylib", "rlib"]
├── pyproject.toml # maturin build config
├── src/
│ ├── lib.rs # Core Rust library
│ └── python/ # Python binding module
│ ├── mod.rs # #[pymodule] definition
│ ├── types.rs # #[pyclass] wrappers
│ └── errors.rs # Python exception types
├── python/
│ └── my_lib/ # Pure Python additions (optional)
│ ├── __init__.py
│ └── py.typed # PEP 561 marker
└── tests/
├── rust/ # Rust unit tests
└── python/ # Python integration tests
Core Workflow
1. Expose Rust Types
use pyo3::prelude::*;
#[pyclass]
#[derive(Clone)]
pub struct MyType {
inner: RustType, // Keep Rust type private
}
#[pymethods]
impl MyType {
#[new]
fn new(value: i64) -> PyResult<Self> {
Ok(Self { inner: RustType::new(value)? })
}
fn process(&self) -> PyResult<String> {
self.inner.process().map_err(|e| e.into())
}
}
2. Register Module
#[pymodule]
fn my_lib(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<MyType>()?;
m.add_function(wrap_pyfunction!(my_function, m)?)?;
Ok(())
}
3. Build & Test
maturin develop # Install in current venv for testing
maturin build --release # Build wheel
pytest tests/python/ # Run Python tests
Reference Guides
Load these as needed based on the task:
| Task | Reference | |------|-----------| | Type mapping between Rust ↔ Python | type-conversions.md | | Converting Rust errors to Python exceptions | error-handling.md | | GIL management and memory safety | memory-gil.md | | Building wheels and publishing to PyPI | build-publish.md | | Testing strategies (Rust + Python) | testing.md | | Debugging common binding issues | debugging.md | | CQLite CQL feature parity checklist | cqlite-parity.md |
Quick Reference
Common Cargo.toml Setup
[lib]
name = "my_lib"
crate-type = ["cdylib", "rlib"]
[dependencies]
pyo3 = { version = "0.22", features = ["extension-module"] }
[features]
extension-module = ["pyo3/extension-module"]
Common pyproject.toml
[build-system]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"
[project]
name = "my-lib"
requires-python = ">=3.8"
classifiers = ["Programming Language :: Rust"]
[tool.maturin]
features = ["pyo3/extension-module"]
python-source = "python" # If you have pure Python code
PyO3 Attribute Quick Reference
| Attribute | Use |
|-----------|-----|
| #[pyclass] | Expose struct to Python |
| #[pymethods] | Impl block with Python-visible methods |
| #[new] | __init__ constructor |
| #[getter] / #[setter] | Property access |
| #[staticmethod] | No self parameter |
| #[classmethod] | Receives cls: &Bound<'_, PyType> |
| #[pyo3(name = "...")] | Rename in Python |
| #[pyo3(signature = (...))] | Custom signature with defaults |
Scan to join WeChat group