One modern lint stack
Directive¶
Python code uses one toolchain: ruff (format and lint), pyrefly (types) and botica (the rules that
can be checked deterministically), all run through prek. The legacy stack is not reintroduced:
black, isort, flake8 (and its plugins), pylint, autopep8, yapf and standalone
pyupgrade.
The type checker stays on. No setting or directive turns it off for a whole file, a project or a
build: # pyrefly: ignore-errors, // @ts-nocheck, "strict": false or an option of the strict
family set to false in tsconfig.json, and typescript.ignoreBuildErrors in next.config. A
type error that cannot be fixed yet is silenced on its line, with the reason.
Why¶
- ruff covers black, isort, flake8, pyupgrade and most of pylint in one fast tool with one config. Stacking the old tools on top means overlapping, conflicting passes and a config spread across five files.
- One toolchain means one configuration and one formatter.
- A checker that is off for a file reports nothing there, and the errors it would report stay in the code. An agent whose build fails on types can turn the checker off instead of fixing them.
Replacements¶
| Legacy | Use |
|---|---|
black, yapf, autopep8 |
ruff format |
isort |
ruff (import sorting, I) |
flake8 + plugins |
ruff lint rules |
pyupgrade |
ruff (UP) |
pylint |
ruff + pyrefly |
| mypy (as the only checker) | pyrefly |
When a legacy tool appears¶
A legacy tool in pyproject.toml or prek.toml is removed, and its intent is expressed through
this stack.
Migration¶
A repository where the checker is off somewhere turns it back on in its own pull request:
- Remove the directive or the setting, and run the checker (
pyrefly check,tsc --noEmit). - Fix the errors it reports. An error that has to stay gets a suppression on its line with the
reason:
# pyrefly: ignore[<code>],// @ts-expect-error <reason>. - When there are too many errors for one pull request, keep the file in the
extend-ignoresof[rules.no-disabled-typecheck]and remove it from there file by file. In pyrefly, abaselinefile holds the existing errors and reports only new ones.
Rules¶
no-disabled-typecheck(BTTOOL001)