返回 Skill 列表
extension
分类: 开发与工程无需 API Key

pyo3-maturin-bindings

使用PyO3和maturin为Rust库创建Python绑定。当在为Rust代码创建Python绑定时使用,包括创建或修改pyfunction/pyclass定义、在Rust和Python之间转换类型、处理跨FFI边界错误、管理GIL和内存、用maturin构建wheel包、发布到PyPI、测试绑定代码或调试绑定问题等。针对CQLite(Cassandra CQL绑定)进行了优化,并跟踪功能对齐。

person作者: jakexiaohubgithub

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 |