Thanks for your interest in contributing. This guide covers how to set up a development environment, the standards your changes must meet, and how to get a pull request merged.
See the README for installation instructions and docs/ARCHITECTURE.md for a tour of the codebase. For cache locations and the environment variables that move them, see docs/CONFIGURATION.md.
Short version for contributors:
git clone https://github.com/michael-denyer/pyLocusZoom.git
cd pyLocusZoom
uv sync --extra dev # the test tools (pytest plugins, hypothesis) are the dev extra
uv tool install prek && prek install # Rust pre-commit, ~10x faster than pre-commit
uv run python -m pytest tests/The hook install step is required — without it, you will only discover lint,
format, markdown, or mermaid failures in CI. We recommend prek,
a drop-in replacement for pre-commit written in Rust; it reads the same
.pre-commit-config.yaml but installs and runs hooks dramatically faster. If
you already use pre-commit, uv run pre-commit install still works. The
mermaid hooks shell out to npx, so you need Node.js 20+ on your PATH
(brew install node on macOS). See docs/DEVELOPMENT.md
for the full dev setup.
Python 3.10, 3.11, and 3.12 are all supported and tested in CI.
- Formatter and linter: ruff, pinned to
version
0.15.2in CI. Run both before committing:If the format check fails, runuv tool run ruff check src/ tests/ uv tool run ruff format --check src/ tests/
uv tool run ruff format src/ tests/to fix. - Tests:
pytestwithpytest-xdistfor parallelism,pytest-randomlyfor order-independence, andpytest-timeoutfor hang detection. Parallelism, the timeout, coverage and marker selection come fromaddoptsinpyproject.toml, so the command carries no flags. Run:uv run python -m pytest tests/
- Docstrings: Google-style for all public functions and classes.
- Mermaid diagrams: validated in CI with both
@probelabs/maid(syntax) and@mermaid-js/mermaid-cli(renderer parity). Keep diagrams in fenced```mermaidblocks. - Markdown:
markdownlint-cli2runs on every.mdfile in CI. - Links:
lycheechecks every link in committed markdown; broken links fail the build. Absolute links to this repository's own files onmainare resolved against the checkout bytests/test_docs_contract.py, not over the network.
CI enforces all of the above on every pull request via
.github/workflows/ci.yml. A PR with lint, format,
markdown, mermaid, link-check, or test failures will not merge.
- Base branch: open PRs against
main. - Tests first: follow test-driven development — add or update tests in
tests/before (or alongside) the implementation. Mock PLINK calls rather than requiring a local install; seetests/test_ld_process.pyfor the pattern. - Changelog: add an entry to
CHANGELOG.mdunder the## [Unreleased]section, using theAdded/Changed/Fixed/Removedcategories. - Docs: update
README.md,docs/USER_GUIDE.md,docs/ARCHITECTURE.md, ordocs/CONFIGURATION.mdwhen your change alters public APIs, adds features, or changes behavior that users rely on. - Example plots: if your change touches a backend or a panel, run
scripts/example_diff.sh. It regenerates the examples and lists the exports whose content changed after normalising generated ids. Generation runs in a temporary directory and leaves the checkout untouched. Exit 1 reports differences; exit 2 reports a failure. Review the changes, then use--keepto accept only changed exports. Acceptance refuses to overwrite manually modified exports. Commit the accepted outputs with the source change. - Commits: keep messages focused on what changed and why. Do not include AI or tool attribution.
- Scope: one logical change per PR. Refactors and feature work belong in separate PRs.
Bugs and feature requests go through GitHub Issues: https://github.com/michael-denyer/pyLocusZoom/issues
Templates are provided and should be used:
- Bug reports
(
.github/ISSUE_TEMPLATE/bug_report.md) must include a minimal reproducible example, expected vs actual behavior, and your environment (pylocuszoom version, Python version, OS, install method). - Feature requests
(
.github/ISSUE_TEMPLATE/feature_request.md) should describe the use case and proposed API, not just the feature name.
Before opening an issue, check docs/USER_GUIDE.md —
many common questions are answered there.