Skip to content

Contributing#

math-spec is an actively maintained and utilised project.

How to contribute#

to report issues, request features, or exchange with our community, just follow the links below.

Developing math-spec#

To find beginner-friendly existing bugs and feature requests you may like to start out with, take a look at our good first issues.

Setting up a development environment#

To create a development environment for math-spec, use pixi.

  1. Install pixi following the official instructions.
  2. Install the development environment in your local clone of the math-spec repository:
pixi install

If you plan to make changes to the code then please make regular use of the following tools to verify the codebase while you work:

  • pre-commit: run pixi run pre-commit-install in your command line to load inbuilt checks that will run every time you commit your changes. The checks include:
  • check no large files have been staged
  • lint python files for major errors
  • format python files to conform with the PEP8 standard
  • type-check the package with pyrefly. You can also run these checks yourself at any time to ensure the tree is clean by calling pixi run lint.
  • pixi run test - run the unit test suite.
  • pixi run test-coverage - the same, with test coverage.
  • pixi run compile-tex - render every model in the tree to standalone LaTeX and compile it, which is how the typeset output is proven to be a real document.
  • pixi run ci - all four gates CI runs — lint, tests, a strict docs build and the LaTeX compile — in the order a failure is cheapest to read. About fifteen seconds; worth a run before you push.

Documentation#

With any contribution, you may need to update / add to the documentation (in the docs directory). We use MkDocs and the Material theme to build and render our documentation, meaning you can write your documentation in Markdown files.

Here are some use-cases that you may come across in which you are considering updating the documentation:

I have updated the README.md

Sections of the README are piped into the site rather than copied wholesale: the homepage includes the badges, the diagram, the model, the load snippet, the development install and the status note, each by name. Edit inside the markers and the site follows. Keep the sections themselves link-free or absolutely linked: a relative link inside one resolves against docs/index.md on the site and against the repository root on GitHub, and only one of those can be right.

I have changed what a model prints

The model in the README and the math block under it on the homepage both come out of examples/dispatch.yaml and its symbol table, so the page shows what the typesetter prints rather than what somebody typed — and the model shown cannot drift from the model rendered:

pixi run python -m tools.home_math           # rewrite the block
pixi run python -m tools.home_math --check   # fail if it has drifted

tools/notation.py does the same for docs/reference/notation.md, out of tests/typesetting/golden/model.yaml. It also wants the four piecewise: models one section of that page is built from, which the extraction from lpspec has not brought over yet — so it raises FileNotFoundError until they arrive, and the committed page is the last one lpspec generated.

I want to add a new page

Add a Markdown file to the top-level in docs, e.g. docs/my-page.md. Then, add a reference to that file within the nav key in mkdocs.yml, e.g.:

nav:
- Home: index.md
- Installation: installation.md
- Getting started: getting_started.md
- My Page: my-page.md

You can also just rely on your document header to define the name in the navigation: my-page.md

# My Page
...

mkdocs.yml

nav:
...
- my-page.md
...
I want to add images to my docs

You should add any new images to the top-level resources/ directory. Within your Markdown, you will be able to reference these as follows:

<figure>
<img src="../resources/filename.png", width="100%", style="background-color:white;", alt="accessible alternative text">
<figcaption>My caption.</figcaption>
</figure>

Or:

![accessible alternative text](../resources/filename.png)

The first approach gives you a bit more power, including having a figure caption.

I want to update the Python API docs

As with example notebooks, we update these pages automatically. So, if you've added content within your project (a new class, module, etc.), you will see them in your next iteration of the documentation.

I want to automatically process a number of files into pages in the docs

You may have configuration files you want to add to the documentation for reference. You should add your workflow to process these files to docs/hooks.py. In that file, you can find examples of how we do it for other files (e.g. the python API docs).

I want to view my documentation changes locally

You can serve your documentation locally by calling pixi run docs-serve from the command line. Once the documentation has been built you will see a link to navigate to in your browser, most likely http://127.0.0.1:8000. When you make changes to your documentation, mkdocs will automatically rebuild everything so that you can check the effects of your changes without needing to rerun manually.

I want to do something else

We recommend exploring the MkDocs and the Material documentation if we haven't answered your question.

Submitting changes#

To contribute changes:

  1. Fork the project on GitHub.
  2. Create a feature branch to work on in your fork (git checkout -b new-fix-or-feature).
  3. Test your changes using pixi run test, or pixi run ci for everything CI will check.
  4. Commit your changes to the feature branch (you should have pre-commit installed to ensure your code is correctly formatted when you commit changes).
  5. Push the branch to GitHub (git push origin new-fix-or-feature).
  6. On GitHub, create a new pull request from the feature branch.

When you contribute for the first time, ensure your reviewer adds you as a contributor!

Pull requests#

Before submitting a pull request, check whether you have:

  • Written the PR title as a conventional commit subject (see below) — this, not a hand-written entry, is what appears in CHANGELOG.md.
  • Added or updated documentation for your changes.
  • Added tests if you implemented new functionality.

When opening a pull request, please provide a clear summary of your changes!

Commit messages#

Merges are squashed, and the resulting subject on main is what release-please reads to build the changelog. So the PR title must be a conventional commit subject:

<type>[(scope)]: <subject>

feat: AST parsing for indexed constraints
fix(parser): where clauses with a trailing comma
docs: describe the two expression tiers

Types are feat, fix, perf, refactor, docs, chore, test, ci, build, style and revert; the first five appear in the changelog and the rest are hidden. A subject the parser cannot read is not an error — the entry simply never appears — so the Conventional commit subject check enforces the format on every pull request.

While the version is pinned to the alpha stream, a breaking marker (!, or a BREAKING CHANGE: footer) is refused, because it moves the base version rather than the alpha counter. Describe the break in the PR body instead. See RELEASING.md.

Beyond the subject line, write whatever body the change deserves — a paragraph or bullet list covering what changed and its impact.

Code conventions#

Start reading our code and you'll get the hang of it.

We mostly follow the official Style Guide for Python Code (PEP8).

We have chosen to use the uncompromising code formatter and linter ruff. When run from the root directory of this repo, pyproject.toml should ensure that formatting and linting fixes are in line with our custom preferences (e.g., maximum line length). To make this a smooth experience, you should run pixi run pre-commit-install after setting up your development environment. If you prefer, you can also set up your IDE to run these two tools whenever you save your files, and to have ruff highlight erroneous code directly as you type. Take a look at their documentation for more information on configuring this.

We require all new contributions to have docstrings for all modules, classes and methods. When adding docstrings, we request you use the Google docstring style.

Releases#

Nothing here is done by hand. release-please opens a release PR from the conventional-commit subjects on main; merging it tags the release, and the tag is what builds and publishes the package. While the project is on the alpha stream that release PR is merged automatically, so every merge to main cuts a version.

The version is never written down in the source tree — it comes from the git tag at build time, and math_spec.__version__ reads it back from the installed package metadata.

See RELEASING.md for the full pipeline, the alpha-stream rules, and the one-time repository setup it still needs.