mirror of
https://github.com/ruvnet/RuView
synced 2026-06-19 11:53:19 +00:00
4ec5b166e6
Three fixes to make maturin develop actually work locally:
1. `python/Cargo.toml` removed `*.workspace = true` inheritance —
the python/ crate is intentionally outside the v2/ workspace
(ADR-117 §5.2) so it needs every `[package]` field local.
2. `python/pyproject.toml` `python-source = "python"` was wrong
because pyproject.toml lives at python/ — maturin was looking for
python/python/. Changed to `python-source = "."` so the
`wifi_densepose/` package directory sibling-to-pyproject is found.
3. `python/src/lib.rs` `#[pymodule] fn wifi_densepose_native` →
`#[pymodule] #[pyo3(name = "_native")] fn wifi_densepose_native`.
PyO3 generates `PyInit__native` from the pyo3-name attribute, which
must match the `module-name` in pyproject.toml's [tool.maturin]
block ("wifi_densepose._native"). Without this attribute the wheel
builds but `import wifi_densepose._native` fails with
ModuleNotFoundError.
## Local validation (P1 acceptance gate)
```
$ python -m venv .venv && .venv/Scripts/python -m pip install maturin pytest
$ VIRTUAL_ENV=… maturin develop --release
…
Finished `release` profile [optimized] target(s)
📦 Built wheel for abi3 Python ≥ 3.10
🛠 Installed wifi-densepose-2.0.0a1
$ .venv/Scripts/python -c 'import wifi_densepose; print(wifi_densepose.__version__, wifi_densepose.__rust_version__, wifi_densepose.hello())'
2.0.0a1 2.0.0-alpha.1 ok
$ .venv/Scripts/python -m pytest tests/ -v
tests/test_smoke.py::test_package_imports PASSED
tests/test_smoke.py::test_version_string_well_formed PASSED
tests/test_smoke.py::test_rust_version_surfaced PASSED
tests/test_smoke.py::test_build_features_listed PASSED
tests/test_smoke.py::test_hello_returns_ok PASSED
tests/test_smoke.py::test_native_module_private PASSED
======================== 6 passed in 0.05s =========================
```
P1 closed. Moving to P2 (core type bindings).
Refs #785, ADR-117 §6.
Co-Authored-By: claude-flow <ruv@ruv.net>
65 lines
2.7 KiB
Rust
65 lines
2.7 KiB
Rust
//! ADR-117 — PyO3 bindings for the WiFi-DensePose Rust core.
|
|
//!
|
|
//! This crate is the compiled half of the `wifi-densepose` v2.x PyPI
|
|
//! wheel. The Python-facing facade lives in `python/wifi_densepose/`
|
|
//! and re-exports symbols from this module under their stable names.
|
|
//!
|
|
//! ## Phase status (per ADR-117 §6)
|
|
//!
|
|
//! - **P1 (scaffold) — this commit**: module loads, version constant
|
|
//! exposed, smoke test passes via maturin develop.
|
|
//! - **P2**: bind `CsiFrame`, `Keypoint`, `PoseEstimate` (next).
|
|
//! - **P3**: bind 4-stage vitals + signal DSP.
|
|
//! - **P4**: pure-Python `wifi_densepose.client` (WS/MQTT) — no Rust
|
|
//! surface needed; lives outside this crate.
|
|
//! - **P5**: cibuildwheel + PyPI publish.
|
|
|
|
use pyo3::prelude::*;
|
|
|
|
/// Version of the bound Rust core. Surfaced to Python as
|
|
/// `wifi_densepose.__rust_version__` so users can correlate wheel
|
|
/// behaviour with the exact `v2/crates/` HEAD it was built from.
|
|
const RUST_CORE_VERSION: &str = env!("CARGO_PKG_VERSION");
|
|
|
|
/// Compile-time identifier for the Rust commit that produced this
|
|
/// wheel. Surfaced for diagnostics. Set via `CARGO_PKG_VERSION` for
|
|
/// now; P5 wires in the git SHA via `vergen`.
|
|
const RUST_BUILD_TAG: &str = env!("CARGO_PKG_VERSION");
|
|
|
|
/// One-line description of which feature flags were enabled at build
|
|
/// time. Helps users debug "is my wheel the slim one or the full one?".
|
|
fn build_features() -> Vec<&'static str> {
|
|
let mut feats: Vec<&'static str> = Vec::new();
|
|
// P2 will turn this into a real cfg-driven list as features land.
|
|
feats.push("p1-scaffold");
|
|
feats
|
|
}
|
|
|
|
/// Quick smoke test exposed to Python. Returns "ok" — used by the
|
|
/// integration tests in `python/tests/test_smoke.py` to assert the
|
|
/// PyO3 module is importable and callable.
|
|
#[pyfunction]
|
|
fn hello() -> PyResult<&'static str> {
|
|
Ok("ok")
|
|
}
|
|
|
|
/// The `_native` module — re-exported in pure-Python as
|
|
/// `wifi_densepose._native`. End users should import the parent
|
|
/// package (`import wifi_densepose`) and never reach into `_native`
|
|
/// directly; the leading underscore is a Python convention marking
|
|
/// it as private.
|
|
///
|
|
/// The function name MUST match the `module-name` in pyproject.toml's
|
|
/// `[tool.maturin]` block — i.e. it must be `_native` because the
|
|
/// pyproject says `module-name = "wifi_densepose._native"`. PyO3
|
|
/// generates the `PyInit__native` symbol from this function name.
|
|
#[pymodule]
|
|
#[pyo3(name = "_native")]
|
|
fn wifi_densepose_native(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
m.add("__rust_version__", RUST_CORE_VERSION)?;
|
|
m.add("__rust_build_tag__", RUST_BUILD_TAG)?;
|
|
m.add("__build_features__", build_features())?;
|
|
m.add_function(wrap_pyfunction!(hello, m)?)?;
|
|
Ok(())
|
|
}
|