Developer Environment

To develop, we suggest using virtual environments together with pip or using pipenv. Once the environment is activated, clone the repo from GitHub

git clone

and install all necessary packages for development

python -m pip install --upgrade --editable .[complete]

Then setup the Git pre-commit hook for Black by running

pre-commit install

as the rev gets updated through time to track changes of different hooks, simply run

pre-commit autoupdate

to have pre-commit install the new version.


Data Files

A function-scoped fixture called datadir exists for a given test module which will automatically copy files from the associated test modules data directory into a temporary directory for the given test execution. That is, for example, if a test was defined in, then data files located in test_schema/ will be copied to a temporary directory whose path is made available by the datadir fixture. Therefore, one can do:

def test_patchset(datadir):
    data_file = open(datadir.join("test.txt"))

which will load the copy of text.txt in the temporary directory. This also works for parameterizations as this will effectively sandbox the file modifications made.


pyhf tests packaging and distributing by publishing in advance of releases to TestPyPI. Installation of the latest test release from TestPyPI can be tested by first installing pyhf normally, to ensure all dependencies are installed from PyPI, and then upgrading pyhf to a test release from TestPyPI

python -m pip install pyhf
python -m pip install --upgrade --extra-index-url --pre pyhf


This adds TestPyPI as an additional package index to search when installing. PyPI will still be the default package index pip will attempt to install from for all dependencies, but if a package has a release on TestPyPI that is a more recent release then the package will be installed from TestPyPI instead. Note that dev releases are considered pre-releases, so 0.1.2 is a “newer” release than 0.1.2.dev3.


Publishing to PyPI and TestPyPI is automated through the PyPA’s PyPI publish GitHub Action and the pyhf Tag Creator GitHub Actions workflow. A release can be created from any PR created by a core developer by adding a bumpversion tag to it that corresponds to the release type: major, minor, patch. Once the PR is tagged with the label, the GitHub Actions bot will post a comment with information on the actions it will take once the PR is merged. When the PR has been reviewed, approved, and merged, the Tag Creator workflow will automatically create a new release with bump2version and then deploy the release to PyPI.

Context Files and Archive Metadata

The .zenodo.json and codemeta.json files have the version number automatically updated through bump2version, though their additional metadata should be checked periodically by the dev team (probably every release). The codemeta.json file can be generated automatically from a PyPI install of pyhf using codemetapy

codemetapy --no-extras pyhf > codemeta.json

though the author metadata will still need to be checked and revised by hand. The .zenodo.json is currently generated by hand, so it is worth using codemeta.json as a guide to edit it.

Release Checklist

As part of the release process a checklist is required to be completed to make sure steps aren’t missed. There is a GitHub Issue template for this that the developer in charge of the release should step through and update if needed.