Instructions for developers and contributors#
PyIBS implements inverse binomial sampling in Python. It requires Python
3.10 or later, NumPy 2.0 or later, and SciPy 1.13 or later. The reference
implementation is ibslike.m in
MATLAB IBS; the
catalogue of deliberate differences lists
the intentional differences and explains their reasons.
The published documentation is at https://acerbilab.org/pyibs/.
Installation instructions for developers#
For a source checkout with development dependencies:
Clone the PyIBS GitHub repository:
git clone https://github.com/acerbilab/pyibs cd pyibs
Create a virtual environment with uv and install PyIBS in editable mode, so changes to the source take effect without reinstalling:
uv venv --python 3.12 .venv uv pip install -e ".[dev]"
Install the pre-commit hooks, which format and check staged files before a commit:
.venv/bin/python -m pre_commit install
Commands on this page use the environment’s interpreter,
.venv/bin/python. On Windows, replace this path with
.venv\Scripts\python.exe, including in the hook-installation command
above. No environment activation is needed. setuptools_scm derives
PyIBS’s version from the Git tags.
Declare dependencies in pyproject.toml: runtime requirements under
dependencies, test requirements under the test extra, and development
requirements under dev. The development extra also includes the test
requirements. Every runtime and test dependency needs a lower bound; CI
tests the lowest permitted versions.
Coding conventions#
Useful background on Python style:
The repository conventions below keep contributions consistent with the existing code.
Code formatting#
The pre-commit hooks run Black at a line length of 79, isort with Black’s profile, and pycln. To check every file:
.venv/bin/python -m pre_commit run -a
Once installed, the hooks check staged files at each commit and may reformat
them. Restage any modified files before committing again. The hooks are
defined in .pre-commit-config.yaml and their formatting settings in
pyproject.toml. CI does not check formatting, so run the hooks locally.
Docstrings#
The docstrings follow the NumPy format. Use the numpydoc example and the docstrings in pyibs/ibs.py as guides.
Random numbers#
Pass an explicit numpy.random.Generator to code that draws random
numbers. A fixed seed must reproduce a run when the sampling schedule does
not depend on timing.
Exceptions#
Use standard Python exceptions where appropriate.
Testing#
The pytest suite lives in pyibs/testing/. It ships with the package
and can be run after installing the test extra with
pytest --pyargs pyibs. From a development checkout, run the full default
suite or a selected test with:
.venv/bin/python -m pytest
.venv/bin/python -m pytest pyibs/testing/test_sampler.py::test_cost
Test requirements:
Run the relevant tests before submitting a change. CI runs the full matrix on pull requests to
mainordev*branches that change the package, examples, installation metadata, or test workflows. It covers Windows, Linux, and macOS with Python 3.10–3.14, plus Python 3.10 with the lowest NumPy, SciPy, and pytest versions allowed bypyproject.toml.Seed every test that draws random numbers so its failure can be reproduced.
State statistical tolerances in standard errors, 4.5 by default. Investigate a failing statistical test; do not reseed it to make it pass.
Use a fake clock advanced by the simulator for timing tests, or make the expected values independent of the machine’s speed. Avoid timing margins that a slow runner can miss.
Some tests port the self-tests of
ibslike.m, the reference implementation.
The integration tests in pyibs/testing/integration/ fit the example
model with PyBADS or PyVBMC, using IBS estimates as the noisy target. The
default checkout run excludes the integration marker. Each integration
test skips when its package is absent or too old: it requires PyBADS 1.5.1
or later or PyVBMC 1.5 or later, respectively. These tests take a few
minutes. To run them:
uv pip install "pybads>=1.5.1" "pyvbmc>=1.5.0"
.venv/bin/python -m pytest -m integration pyibs/testing/integration/test_pybads.py -s -v
.venv/bin/python -m pytest -m integration pyibs/testing/integration/test_pyvbmc.py -s -v
Code documentation#
Build the documentation with
Sphinx. The
source is in docsrc.
From the repository root, with the environment’s bin directory
(Scripts on Windows) first on the PATH:
PATH="$PWD/.venv/bin:$PATH" make -C docsrc github
The target copies the example notebooks into the documentation source,
builds the site, copies it to the gitignored docs/ directory, and removes
the temporary notebook copies. Open docs/index.html to view the result.
On Windows, use .venv/Scripts in the PATH command above, or run
.\make.bat github from docsrc in cmd with that directory on
PATH. The build must produce no warnings.
If pages or navigation do not update correctly, clear the generated site
in docs/ and the cached docsrc/_build directory, then rebuild:
make -C docsrc clean
On Windows, run .\make.bat clean from docsrc in cmd instead.
General structure#
Each public class or function needs a hand-written .rst page in
docsrc/source/api/classes/ or docsrc/source/api/functions/. Give it a
short introduction and an autoclass or autofunction directive to
render the docstring, for example:
.. autoclass:: pyibs.IBS
:members:
Add the page to its table of contents: documentation.rst for a headline
page, and api/classes/classes.rst or api/functions/functions.rst.
Keep the documentation in step with changes to the public API.
Examples#
The example notebooks live in examples/ and are installed as
pyibs.examples. Their model is in psycho_model.py. The documentation
renders saved outputs without executing the notebooks.
To rerun them in place, with PyBADS, PyVBMC, matplotlib and ipykernel
installed in the environment:
uv pip install nbconvert ipykernel matplotlib "pybads>=1.5.1" "pyvbmc>=1.5.0"
PATH="$PWD/.venv/bin:$PATH" make -C examples/scripts run
After rerunning the notebooks, regenerate their code in
examples/scripts/ with make -B -C examples/scripts. Keep the
environment first on PATH and install nbconvert, IPython, and the Black
and isort versions specified by the pre-commit hooks. Edit the notebooks;
the scripts are generated files.
git commits#
Commits follow the conventional commits style. See the cheat sheet for examples.
Use a feature branch for a contribution and submit completed changes with
passing tests through a pull request. For example, replacing
<new-feature> with your branch name:
git checkout -b <new-feature>
[... do stuff and commit ...]
git push -u origin <new-feature>
[... open a pull request on GitHub when ready ...]
See Feature Branch for background on this workflow.
Changelog#
In the same commit as a change to results, the interface, or what a
script sees or has to handle, add one or two sentences for users under
Unreleased in CHANGELOG.md. A change that
can break a script written for the last release or alter its results also
needs an entry in the opening “Upgrading from” list. When a change adds,
removes, or alters an intentional difference from ibslike.m, update the
corresponding entry in the catalogue.