Contributing¶
Development setup¶
git clone https://github.com/astroai/torchfits.git
cd torchfits
pixi install
pixi run preflight-push # quick check while editing
pixi run test # full unit suite
The project uses pixi for environment management,
ruff for linting, and
pytest for testing. Detailed coding guidelines live in
AGENTS.md.
Verify tiers¶
| When | Command |
|---|---|
| During edits | pixi run preflight-push |
| Before push / PR | pixi run ci-local |
| Before tag | pixi run release-gate |
Dependency policy¶
Every package must be installed through pixi. Never run pip install,
pip install -e ., python -m pip install, conda install, mamba install,
pipx install, or any equivalent outside of an activated pixi environment.
The pixi lockfile is the reproducibility contract for this repository;
mixing it with bare-pip / bare-conda / system installs breaks the lockfile
and the CI gates. If you find yourself reaching for one of the commands
below, stop and add a [dependencies] entry in pixi.toml (or a feature's
[feature.<name>.dependencies]) instead, then pixi install.
Do
pixi install— install the workspace as declared inpixi.toml.pixi add <pkg>— add a dependency topixi.tomland re-lock.pixi run <task>— run scripts and tests; tasks are defined inpixi.tomland resolve dependencies from the lockfile.
Don't
pip install .../python -m pip install ...outside a pixi env.conda install .../mamba install ...outside a pixi env.pipx install ...(creates a separate venv that drifts from the lockfile).pip install -e .typed directly into a shell, even "just to try it".
Documented exceptions
pip install -e .invocations inside any[tasks]or[feature.<name>.tasks]block ofpixi.tomlrun inside an activated pixi env and are intentional — they rebuild the C++ extension against the pixi-managed dependencies already on$PATH. They are not bare-pip installs. (In particular,bench-gpu-installunder[feature.gpu.tasks]is the canonical pixi-tasked reinstallation of the C++ extension with--no-depsagainst the pixi-managed torch.)pip install -r requirements.txtstyle flows do not exist in this repo and must not be added; pixi is the single source of truth for the environment.
Repository layout¶
src/torchfits/ Python package
src/torchfits/cpp_src/ C++ native extension (nanobind + CFITSIO)
extern/cfitsio/ Vendored CFITSIO sources (via extern/vendor.sh)
tests/ Unit and integration tests
benchmarks/ Benchmark scripts and replay gates
docs/ Documentation (zensical)
overrides/ Docs theme templates (zensical custom_dir)
examples/ Runnable example scripts
scripts/ CI, docs, and bench helpers
Local-only (gitignored): build/, site/, benchmarks_results/ (bench run
output — publish selected CSVs under docs/assets/bench/<run-id>/).
Native extension¶
The C++ extension is built by scikit-build-core with nanobind bindings. Populate vendored sources with:
./extern/vendor.sh
Rebuild after C++ changes (default and test envs do not share the extension — rebuild each env you will run):
pixi run -- pip install -e . --no-build-isolation
pixi run -e test -- pip install -e . --no-build-isolation
Or pixi run dev when you want the default-env editable install used by
example verification tasks.
C++ code conventions¶
- No inline RAII structs in
.cppfiles. Use the shared guards from the headers below instead. FitsHandleGuard(cache.h) — RAII wrapper that alwaysfits_close_files a privately ownedfitsfile*.MMapHandle(hardware.h) — RAII wrapper formmapregions. Construct with a filename (open + mmap) or adopt an existing mapping viaMMapHandle(ptr, size, fd).- If a new resource requires RAII, add the guard to the appropriate shared header rather than defining an inline struct at the usage site.
Testing¶
Minimum before a PR:
pixi run preflight-push
pixi run -e test -- pytest tests/test_api.py tests/test_table.py tests/test_cli.py -q
Full suite / pre-push:
pixi run test
pixi run ci-local
Upstream parity + docs contract (also part of the release gate):
pixi run release-gate
Benchmarks¶
Quick FITS benchmark sweep:
pixi run bench-all
Published multi-host benchmark runs (release docs): see Release Checklist
(bench-exhaustive-local + CANFAR CPU/CUDA + bench-release-scorecard).
Include benchmark evidence in PRs that touch performance-sensitive paths.
Documentation policy¶
README.md: user-facing overview only.docs/api.md: public API reference. Update if a PR changes a public API.docs/roadmap.md: FITS I/O roadmap and parity tiers.docs/parity.md: compatibility matrix. Update if support status changes.docs/changelog.md: release notes, Keep a Changelog format.docs/benchmarks.md: benchmark methodology and results.- Published site: stable = latest
v*tag at astroai.github.io/torchfits; edge = tip ofmainat astroai.github.io/torchfits/edge (no SemVer release required). Local dual tree:pixi run docs-build-pagesorbash scripts/build_docs_pages.sh.
PR guidelines¶
- Keep PRs focused on a single concern.
- Include tests for behavior changes.
- Run
pixi run preflight-push(andpixi run ci-localbefore merge/push). - Do not commit local scratch files, benchmark artifacts, or
.envfiles. - Docs must match the public façade; do not document env vars absent from
src/.
Release process¶
See release.md for the maintainer checklist.