RosettaStune is a lightweight unit registry for cross-schema linked data. It uses a Rust core for fast alias resolution and a Python layer for optional conversions to Pint, Astropy, and SymPy.
- Unit alias policy and contribution guide: docs/unit-alias-policy.md
- Agent and contributor workflow: AGENTS.md
python/rosettastune/data/lexicon.jsonldis the language-agnostic source of truth.- The Rust extension parses the JSON-LD lexicon and resolves identifiers locally.
- The Python wrapper converts resolved canonical units into whichever unit library is available.
- Pint for runtime array math and engineering calculations.
- Astropy for strict scientific unit handling.
- SymPy for symbolic expressions and algebra.
- Open this repository in the included dev container: .devcontainer/devcontainer.json
- The container installs Python, Rust,
llvm-tools-preview, andcargo-llvm-covduringpostCreateCommand.
make install-devIf your Python executable is not the project venv default, override it:
make install-dev PYTHON=/path/to/pythonThe project includes a task-oriented Makefile: Makefile
make help
make fmt
make test
make ciCommon tasks:
make snapshot-updaterefreshes Rust insta snapshots.make coverage-pythongeneratescoverage.xml,coverage.txt, andpytest-junit.xmlvia pytest defaults.make coverage-rustgeneratesrust-coverage.lcov(requirescargo-llvm-cov).
- Build the extension with Maturin.
- Run Rust tests and snapshot checks with Cargo.
- Run Python tests with Pytest.
cargo fmt --check
cargo test
python -m pip install -e '.[dev]'
python -m pytest- CI workflow: .github/workflows/ci.yml
- Coverage thresholds source of truth: Cargo.toml in
[package.metadata.coverage] - CI enforces both:
- Python coverage minimum (
python_min) - Rust line coverage minimum (
rust_min) viacargo llvm-cov
- Python coverage minimum (
- On published releases, CI uploads coverage artifacts to the release:
pytest-junit.xmlcoverage.xmlcoverage.txtrust-coverage.lcovrust-coverage.txt
- Confirm local checks pass:
make ci- Confirm coverage thresholds in
Cargo.tomlunder[package.metadata.coverage]are intentional. - Ensure version metadata is updated where needed (
Cargo.toml,pyproject.toml). - Push changes to
mainand create/publish a GitHub release tag. - Wait for the
release-assetsjob in.github/workflows/ci.ymlto succeed. - Verify release assets include:
pytest-junit.xmlcoverage.xmlcoverage.txtrust-coverage.lcovrust-coverage.txt
- If release coverage/upload fails, inspect workflow logs for:
- missing
cargo-llvm-cov - coverage threshold failures
- pytest import/environment issues
- missing
ModuleNotFoundError: No module named rosettastunewhile running tests:- Use the project venv interpreter and install editable deps first:
make install-dev
make test- Or override `PYTHON` explicitly:
make test PYTHON=/path/to/python-
error: no such command: llvm-cov:- Ensure
cargo-llvm-covis installed andllvm-tools-previewis available. - The dev container and CI install both automatically.
- Ensure
-
PyO3 import/init mismatch errors:
- Ensure Maturin and PyO3 module names match:
pyproject.toml:module-name = "rosettastune._rosettastune"src/lib.rs:#[pymodule] fn _rosettastune(...)
- Ensure Maturin and PyO3 module names match:
-
Snapshot drift in Rust tests:
INSTA_UPDATE=always cargo test- Add canonical entry and aliases in
python/rosettastune/data/lexicon.jsonld. - Add backend mappings in
python/rosettastune/api.pyfor Pint, Astropy, and SymPy. - Update or regenerate snapshots with
INSTA_UPDATE=always cargo test. - Add or adjust Python tests in
tests/test_rosettastune.py.