Pre-commit Hooks¶
Pre-commit hooks are by default executed, as their name suggests, before every commit. They serve as a guardrail to ensure code quality and other useful stuff.
The hooks can perform tasks, such as formatting code or trimming trailing whitespace, or perform specific checks. When a key check fails (such as mypy
static type checking), the commit cannot be made until the issue has been resolved.
Tip
Pre-commit hooks can be called on more events than on commit. All options, and their descriptions, can be found here.
Using pre-commit hooks¶
In order to use pre-commit hooks in your projects:
- The
pre-commit
package needs to be installed:- Refer to my
pyproject.toml
. - Accomplished using
poetry add --group="dev" pre-commit
.
- Refer to my
- The desired hooks need to be defined in
.pre-commit-config.yaml
. - The hooks need to be installed:
- Run
pre-commit install
- Run
Manually executing and updating pre-commit hooks
Pre-commit hooks can be run on demand, as well as automatically updated to the latest version.
I have elected to create poetry
scripts for both applications (refer to pyproject.toml
).
Executing pre-commit hooks on demand
To run your pre-commit hooks on demand, instead of only when their trigger condition is met, use the command pre-commit run --all-files
.
Updating pre-commit hooks
To update all pre-commit hooks to their latest version, use the command pre-commit autoupdate
.
Pre-commit¶
These hooks are from the default pre-commit
repository:
check-yaml
:- Validates YAML files.
end-of-file-fixer
:- Ensures a blank line at each file's end.
trailing-whitespace
:- Trims trailing whitespace from each line's end.
Mypy¶
These hooks are from the mypy
repository:
mypy
:- Static type checking for Python code.
Ruff¶
These hooks are from the astral-sh ruff
repository:
Use Ruff
instead of isort
, black
and flake8
.
For those of you who have not yet heard about Ruff; it is a drop-in replacement for isort
, black
and flake8
combined. Within VSCode, it takes care of linting, formatting and import sorting.
Ruff works out of the box, and completely blows aforementioned packages out of the water in terms of performance, due to being Rust-based.
ruff
:- Linter for Python code.
ruff-format
:- Formatter for Python code.
Full configuration¶
Check out the full .pre-commit-config.yaml
here.
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- id: check-yaml
args: [--unsafe, --allow-multiple-documents]
- id: check-ast
- id: check-builtin-literals
- id: check-docstring-first
- id: check-json
- id: check-merge-conflict
- id: check-toml
- id: debug-statements
- id: detect-private-key
- id: end-of-file-fixer
exclude: \.json$
- id: fix-byte-order-marker
- id: fix-encoding-pragma
args: [--remove]
- id: mixed-line-ending
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.2
hooks:
- id: ruff
name: Ruff Linter
types_or:
- python
- pyi
- jupyter
args: [--fix]
- id: ruff-format
name: Ruff Formatter
types_or:
- python
- pyi
- jupyter
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
hooks:
- id: mypy
name: Mypy
exclude: |
(?x)(
^typings/
)
args: [--ignore-missing-imports]