Code quality¶
Pre-commit hooks¶
Install the hooks once per checkout:
pre-commit install
From then on, every git commit runs the configured hooks. The full
set (.pre-commit-config.yaml):
clang-format— C++ formatter for*.cxx,*.cpp, and*.hfiles.ruff(lint with--fix, Python only) andruff-format(Python plus notebook code cells) — Python lint + formatter.jupytext --sync— keeps tutorial notebook*.ipynbfiles and their paired*.mdmirrors in lockstep.check-notebook-executed— fails if any code cell in a tracked.ipynblacks anexecution_count. Sphinx renders the committed outputs as-is, so re-run the notebook end-to-end before committing.nmhit-format— formatter for HIT input files (*.i).check-copyright— adds or refreshes the MIT copyright header on source files.check-dependencies— verifies that every version string flagged with# dependencies: <DEP>.<FIELD>matches the canonical value inscripts/dependencies.yaml(see Dependency pinning).check-compat-matrix/render-compat-matrix— keep the torch compatibility table indoc/content/installation/compatibility.mdin sync withdoc/content/installation/compatibility.yaml.actionlint— lints the GitHub Actions workflow files under.github/workflows/.
Run the whole battery against the working tree at any time:
pre-commit run --all-files
Linting and formatting¶
Both linters run automatically through pre-commit, but you can invoke them directly:
ruff check . # lint (with auto-fix: `ruff check --fix .`)
ruff format . # format
The [tool.ruff.lint] section of pyproject.toml pins the enabled rule
families (E, F, W, I, B, UP) and [tool.ruff] configures
ruff format as the canonical Python formatter. The lint job in
.github/workflows/python.yaml gates every PR.
For C++ formatting, ensure your editor or IDE picks up the
.clang-format file at the repository root. The pre-commit hook covers
the same files (*.cxx, *.cpp, *.h) on commit.
Type checking¶
Python type checking is performed by
pyright. The default scope
(set in pyproject.toml [tool.pyright]) is neml2, tests,
benchmark, scripts, and doc. Run from the repository root:
pyright # check everything in scope
pyright neml2/types # restrict to one subpath
CI runs pyright against the editable install (the typecheck job in
.github/workflows/python.yaml); the editable install resolves
import neml2.* to the in-tree source, so pyright generally sees the
same sources the test suite does. The compiled pybind extension is
resolved through auto-generated .pyi stubs co-located with their
.so; the neml2-stub console script regenerates them by running
pybind11-stubgen against the fully installed package, and CI invokes
it between pip install and pyright.