Developer guide#
- Release:
5.0.0
- Date:
Sep 16, 2026
How to set up a development environment, run the checks that continuous integration runs, and contribute to CFPQ_Data. If you only want to use the package, start with Getting started instead.
Development setup#
CFPQ_Data requires Python 3.11–3.13 (pyproject.toml declares
>=3.11,<3.14). The canonical development environment is Poetry — all
CI workflows install their dependencies through it:
poetry install --with dev,test,docs
poetry run pip install .
--with dev,test,docspulls the three dependency groups frompyproject.toml: developer tools (black,pre-commit,pytest,boto3), test extras (pytest-cov,codecov), and the Sphinx docs stack.The project is declared with
package-mode = false, so Poetry installs only the dependencies;poetry run pip install .then installscfpq_dataitself fromsetup.py.requirements/*.txtare read bysetup.pyto declare the distribution’s install requirements on PyPI; the Poetry groups inpyproject.tomldrive the development environment and CI.
Pre-commit#
Formatting and hygiene checks run through pre-commit. The hook list —
black formatting plus whitespace, YAML, and requirements-file fixers, and a
version-sync check that fails when cfpq_data/config.py and
pyproject.toml declare different versions — is defined in
.pre-commit-config.yaml, which is the source of truth; do not
maintain a copy of it elsewhere.
Install the git hook once so the checks run on every commit:
pre-commit install
Run the full pass manually (this is what CI does):
pre-commit run --all-files --color always --verbose --show-diff-on-failure
Format a single file with black directly:
black <path>
CI runs this full pass on every push and pull request
(.github/workflows/lint.yml).
Test pipeline#
The test suite is pytest with doctests enabled: the Examples
sections of public docstrings are executed as tests, so the documented
behavior and the tested behavior are the same code. The canonical local
command (the one CI runs):
poetry run pytest --doctest-modules -vv -s cfpq_data tests
A single module or function:
poetry run pytest tests/graphs/utils/test_add_reverse_edges.py
Doctest discovery and test paths are configured in
pyproject.toml([tool.pytest.ini_options]).tests/mirrors the package layout (e.g.tests/graphs/generators/forcfpq_data/graphs/generators/).
Continuous integration:
.github/workflows/tests.yml— runs the suite on every push and pull request across a matrix of Linux, macOS, and Windows with Python 3.11..github/workflows/coverage.yml— runs the same suite with--cov=cfpq_dataand uploads the report to Codecov.
Docs build and deploy#
The documentation is built with Sphinx from the docs/ directory; the
canonical local instructions (installing the docs dependencies, building the
HTML, checking links) live in docs/README.md. Two policies matter:
No-warnings policy. The build runs with
-W --keep-going(set indocs/Makefile), so any Sphinx warning — including an unresolved cross-reference undernitpicky = True— fails the build. Fix warnings; do not suppress them.Full link check.
sphinx-build -b linkcheckverifies every local target and external URL (two documented exceptions indocs/conf.py); it exits non-zero on broken or timed-out links.Resilient inventory fetches. Intersphinx inventories are fetched with retries on transient connection errors (
docs/conf.py); a persistent failure still warns and fails the build.
Both the build and the link check run in CI on every push and pull request
(.github/workflows/docs.yml).
Deployment. Pushing to master deploys the site:
.github/workflows/deploy_docs.yml builds the HTML and publishes
docs/_build/html to the gh-pages branch, which GitHub serves as
the project website (https://formallanguageconstrainedpathquerying.github.io/CFPQ_Data).
The workflow skips forks — it runs only for the owning repository.
Package deploy#
Cutting a release — version bump, changelog, vX.Y.Z tag, and the
automated PyPI publish (Trusted Publishing) plus dataset publishing — is
documented in Release process.
Contribution guidelines#
Branching model#
dev— the stable development branch; all work merges here first.master— the protected release branch. A release mergesdevintomastervia a pull request and then pushes avX.Y.Ztag matching the package version (see Release process).feature/XXX-short-description— one feature branch per task; never combine multiple tasks in a single branch.
Commits#
Conventional Commits with exactly one subtask identifier, one commit per atomic subtask:
feat(XXX-SN): description
fix(XXX-SN): description
docs(XXX-SN): description
XXX is the task ID and SN a single subtask identifier (ranges or
lists are not allowed). Commit messages must explain why the change was
made, not only what it does.
Quality gate#
Before a feature branch merges to dev, all of the following must pass —
no exceptions:
The full test suite: 0 failures, 0 skipped.
The full pre-commit pass: no errors.
The docs build: exit 0 under the no-warnings policy.
The link check: no broken or timed-out links.
Merge strategy#
Rebase the feature branch onto dev and fast-forward dev to it —
linear history, no squash, so every subtask commit keeps its own message.
Adding graphs and grammars#
New dataset entries follow the contribution templates in .github/
(issue and pull-request templates for graphs and grammars); see the “How to
add a new graph?” section of the README.