mirror of
https://github.com/headroomlabs-ai/headroom.git
synced 2026-08-27 14:17:10 -04:00
The python `DiffCompressor` is replaced by a thin pyo3-backed shim that delegates to `headroom._core.DiffCompressor`. There is no python implementation and no env-var fallback — the wheel is a hard import. Why now: opt-in defaults don't drive python retirement. Byte-equal parity was already proven across 27 fixtures (stage 3a); keeping a shadow python impl behind a flag is a permanent maintenance cost with no operational benefit. Stage 3b deletes ~700 lines of python parser / scorer / formatter code; the rust crate has its own coverage. Surface preserved: - `headroom.transforms.diff_compressor.DiffCompressor` — same class name, same `__init__`, same `compress(content, context)` shape. Returns python `DiffCompressionResult` dataclasses so call sites that destructure with `asdict()` work unchanged. - `DiffCompressorConfig` and `DiffCompressionResult` dataclasses kept. - Sidecar `compress_with_stats(...)` exposes the rust-only `DiffCompressorStats` (per-file hunk drops, context lines trimmed, file_mode normalizations) for observability. Removed: - Python parser / scorer / formatter (~700 lines). - Internal `DiffHunk` / `DiffFile` parser dataclasses (rust crate has parallel coverage). - 12 tests that probed `_parse_diff` / `_score_hunks` or the deleted parser dataclasses. The 29 public-API tests in `test_diff_compressor.py` remain and now exercise the rust backend through the same import path. - `HEADROOM_DIFF_COMPRESSOR_BACKEND` env var — no longer meaningful. Build: - `scripts/build_rust_extension.sh` runs `maturin develop` and symlinks the built `.so` into `headroom/` so `import headroom._core` resolves past the in-tree package shadowing the maturin overlay. - `.gitignore` excludes the symlinks and allowlists the build script. Tests: - 544 transforms pass; 33 rust-vs-fixture parity tests guard the pyo3 bridge against regressions (`tests/test_transforms/test_diff_compressor_rust_parity.py`). - Mypy clean.
45 lines
1.7 KiB
Bash
Executable file
45 lines
1.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Build the Rust → Python extension (headroom._core) and link it into the
|
|
# in-tree `headroom/` package so `import headroom._core` resolves.
|
|
#
|
|
# Why a wrapper script: `maturin develop` builds the `.so` and installs it
|
|
# into the venv's site-packages, but the in-tree `headroom/` source
|
|
# directory (loaded via `pip install -e .`) shadows that on sys.path.
|
|
# Python finds `headroom/__init__.py` at the project root before reaching
|
|
# the maturin overlay, so `import headroom._core` fails. Symlinking the
|
|
# built `.so` into `headroom/` fixes the lookup with zero copies.
|
|
#
|
|
# Idempotent. Safe to run repeatedly. Requires `maturin` in PATH (i.e.
|
|
# inside the project venv).
|
|
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
if ! command -v maturin >/dev/null 2>&1; then
|
|
echo "error: maturin not found. Activate the venv first:" >&2
|
|
echo " source .venv/bin/activate" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Build the wheel + install into the venv site-packages.
|
|
maturin develop -m crates/headroom-py/Cargo.toml
|
|
|
|
# Locate the built `.so`. `maturin develop` writes it under
|
|
# `crates/headroom-py/python/headroom/_core.cpython-<ver>-<platform>.so`.
|
|
SO_FILE=$(find crates/headroom-py/python/headroom -maxdepth 1 \
|
|
-name "_core.cpython-*.so" -o -name "_core.cpython-*.dylib" -o -name "_core.pyd" \
|
|
2>/dev/null | head -1)
|
|
|
|
if [[ -z "$SO_FILE" ]]; then
|
|
echo "error: maturin develop succeeded but produced no _core.* binary." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Symlink into the in-tree package dir.
|
|
LINK_NAME="headroom/$(basename "$SO_FILE")"
|
|
ln -sf "$(pwd)/$SO_FILE" "$LINK_NAME"
|
|
echo "linked: $LINK_NAME -> $SO_FILE"
|
|
|
|
# Smoke-test the import to fail loudly if anything is misconfigured.
|
|
python -c "from headroom._core import DiffCompressor; print('headroom._core OK:', DiffCompressor)"
|