🔧 mypy: enable strict type checking on src#795
Merged
Conversation
The mypy pre-commit hook excluded all of `src/`, so nothing was actually type-checked. Enable it: drop `src/.*` from the hook's exclude and add a strict `[tool.mypy]` config (`strict = true`). Strictness is enforced everywhere rather than ratcheted up flag by flag. The 17 modules that already pass are checked now; the 35 not yet annotated are listed under an `ignore_errors` override and get removed from that list one by one as they are typed. The global strictness is never relaxed to silence errors; the goal is to empty that list. Third-party deps without type information (node_graph, aiida_pythonjob, kiwipy, yaml, tabulate) are handled with `ignore_missing_imports`. Pin `mypy~=2.1.0` in the `pre-commit` extra so the hook environment provides it in CI; update the lockfile accordingly.
The mypy pre-commit hook excluded all of `src/`, so nothing was actually type-checked. Enable it: drop `src/.*` from the hook's exclude and add a strict `[tool.mypy]` config (`strict = true`). Strictness is enforced everywhere rather than ratcheted up flag by flag. The 17 modules that already pass are checked now; the 35 not yet annotated are listed under an `ignore_errors` override and get removed from that list one by one as they are typed. The global strictness is never relaxed to silence errors; the goal is to empty that list. On top of `strict`, enable several off-by-default error codes (`deprecated`, `exhaustive-match`, `mutable-override`, `possibly-undefined`, `redundant-self`, `truthy-iterable`, `unimported-reveal`, `unused-awaitable`); all pass on the checked modules. Third-party deps without type information (node_graph, aiida_pythonjob, kiwipy) are handled with `ignore_missing_imports`; yaml and tabulate are checked against the types-PyYAML and types-tabulate stubs in the `pre-commit` extra, pinned to match the runtime package versions. Run the hook with `language: system` so it uses the mypy from the activated dev/CI environment instead of building an isolated env that cannot import the project, and with `pass_filenames: false` against a fixed `files = ['src/aiida_workgraph']` target so every run checks the whole tree (an incremental commit can no longer miss a broken caller in an unchanged module). Pin `mypy~=2.1.0` in the `pre-commit` extra so that environment provides it, and update the lockfile accordingly.
elinscott
approved these changes
Jun 25, 2026
elinscott
left a comment
Collaborator
There was a problem hiding this comment.
The mypy pre-commit hook excluded all of src/
... or, indeed, did not exist in the first place 🤦
I would also be in favour of a github test that runs mypy without the list of files to skip, just so we don't forget to eventually get that list down to zero.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The mypy pre-commit hook excluded all of
src/, so nothing under it was ever actually type-checked. This turns it on with a strict config and gets the already-clean modules checked, without a big annotation push up front. The main decisions:strict = trueis enforced everywhere; modules that aren't annotated yet are parked in anignore_errorslist that shrinks one module at a time. Global strictness is never relaxed to silence errors, so the list only ever gets emptied (the opposite of ratcheting strictness up flag by flag).strict, a few off-by-default error codes are enabled (deprecated,possibly-undefined,mutable-override,truthy-iterable,exhaustive-match, etc.); all pass on the checked modules.yamlandtabulateare checked against real stubs (types-PyYAML,types-tabulate, pinned to the runtime package versions); the genuinely untyped deps (node_graph,aiida_pythonjob,kiwipy) stay onignore_missing_imports.language: systemandpass_filenames: falseagainst a fixedsrc/aiida_workgraphtarget, so a commit,pre-commit run --all-files, and a baremypyall check the whole tree (an incremental commit can't pass while breaking a caller in an unchanged module).mypyis pinned~=2.1.0in thepre-commitextra, matching aiida-core.explicit-overrideis left for a follow-up, since requiring@overridemeans a sweep across the existing class hierarchies.