Contributing¶
Contributions are welcome. This guide covers the development setup, coding standards, and the pull request process.
Development setup¶
CCA-Zoo uses uv for dependency management, both in CI and for
local development. A uv.lock is committed so everyone (and CI) resolves the exact same
dependency versions.
1. Clone and install¶
uv sync creates .venv for you; prefix commands with uv run, or source .venv/bin/activate
first. For documentation development:
For a specific optional extra (e.g. to work on the deep module):
If you don't want to use uv, pip install -e ".[dev]" also works, but won't use the lockfile.
2. Run tests¶
uv run pytest -m "not slow" # fast tests only (no torch / numpyro / xgboost required)
uv run pytest -m slow # deep, probabilistic, and tree tests (requires extras)
uv run pytest --cov=cca_zoo # with coverage report
3. Lint and format¶
uv run ruff check . # lint
uv run ruff format --check . # format check
uv run ruff format . # auto-format
Optionally, install pre-commit to run these (plus mypy) automatically on every commit:
4. Type checking¶
5. Build docs locally¶
uv run mkdocs serve # live-reload preview at http://127.0.0.1:8000
uv run mkdocs build --strict # build static site into site/
Coding standards¶
All contributions must comply with the following:
- Python ≥ 3.10 only. Use
X | Yunions,list[x]/dict[x]/tuple[x]generics. - Google-style docstrings on all public classes and methods with Args, Returns, Raises, and Example sections.
- Full type annotations —
mypy --strictmust pass cleanly. - No
try/except— write code that does not need them. - No
print— useloggingif diagnostic output is needed. - 100% test coverage — every new code path needs a test.
- No
# pragma: no cover— this is banned.
Adding a new model¶
- Create the implementation file in the appropriate subpackage
(e.g.
cca_zoo/linear/_mymodel.py). - Inherit from
BaseModel(linear/nonparametric) orBaseDeep(deep). This gets youtransform,fit_transform,score,pairwise_correlations,get_factor_loadings, and correct sklearnget_params/set_params/tags for free — implementfitonly. - Add Google-style docstrings including the mathematical objective and reference(s).
- If any constructor parameter has a documented range (e.g. a ridge parameter in
[0, 1]), declare it in_parameter_constraints(merging in the parent class's, e.g.{**BaseModel._parameter_constraints, "c": RIDGE_PARAMETER}— seecca_zoo/_utils/_param_constraints.pyfor shared constraint fragments andcca_zoo/linear/_mcca.pyfor an example). This is optional but recommended: it turns an invalid parameter into a clear error atfit()time instead of a cryptic failure deep in the linear algebra. - Export from the subpackage's
__init__.pyand add to__all__. Doing this is also what gets your model automatically covered bytests/test_sklearn_compat.py's generic sklearn-estimator-contract checks (get_params/set_paramsround-tripping,repr, init purity) — no per-model test needed for that part. - Write tests in
tests/<subpackage>/test_mymodel.pycovering, at minimum:fitcompleting without error,transform/fit_transformoutput shapes,scoreshape and value range, and — where a closed-form or known-correct reference solution exists — a correctness check against it (seetests/linear/test_eigendecomposition.pyfor the established pattern). If you added_parameter_constraints, add a rejection test per constraint (seetests/linear/test_parameter_constraints.py). - Add a
cca_zoo.<subpackage>.MyModelentry to the relevantdocs/api/*.mdpage —tests/test_docs_coverage.pyenforces this. - Open a pull request against
main.
Pull request guidelines¶
- Keep PRs focused — one feature or fix per PR.
- Include tests for all new/changed behaviour.
- Ensure
uv run ruff check .,uv run ruff format --check .,uv run mypy cca_zoo, anduv run pytest -m "not slow"all pass before requesting review. - Reference any related issues in the PR description.
Reporting issues¶
Use GitHub Issues to report bugs or request features. Please include:
- A minimal reproducible example
- The version of cca-zoo (
python -c "import cca_zoo; print(cca_zoo.__version__)") - Your Python version and OS