Coding Style¶
Pre-commit¶
Getting started¶
To get started with pre-commit, follow these steps:
Install pre-commit. To do so, follow the pre-commit installation instructions.
$ pip install pre-commit
Create a
.pre-commit-config.yamlconfiguration file. To get started use sample config:$ pre-commit sample-config > .pre-commit-config.yaml
Here is another
.pre-commit-config.yamlto start with. Based on Django.pre-commit-conifg.yaml.# See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v3.2.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - repo: https://github.com/PyCQA/isort rev: 5.9.3 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 rev: 4.0.1 hooks: - id: flake8 additional_dependencies: ['flake8-quotes', 'flake8-todos', 'flake8-docstrings'] # args: # - --show-source # Instruct flake8 to show sorce along with error. Specify in setup.cfg - repo: https://github.com/pre-commit/mirrors-eslint rev: v7.32.0 hooks: - id: eslint
Install the git hook scripts
run
pre-commit installto setup the git hook script:$ pre-commit install pre-commit installed at .git\hooks\pre-commit
Now
pre-commitwill run automatically ongit commit.
(Optional) Run pre-commit against all files:
$ pre-commit run --all-files Trim Trailing Whitespace.......................................Passed Fix End of Files...............................................Passed Check Yaml.....................................................Passed Check for added large files....................................Passed Trim Trailing Whitespace.......................................Passed Fix End of Files...............................................Passed Check Yaml.....................................................Passed Check for added large files....................................Passed
If you do not specify the
--all-filesoption,pre-commitwill run only against staged files.
Tips and tricks¶
Execute pytest with each commit¶
You can use local repository to define in-place hook.
# FILE: .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: pytest
name: execute pytest
language: python
entry: pytest
pass_filenames: false
stages: [commit]
additional_dependencies: ['pytest']
Validate commit message¶
To make this work, you also need to install pre-commit as commit-msg hook.
$ pre-commit install -t commit-msg
pre-commit installed at .git\hooks\commit-msg
You can use local repository and pygrep language to validate commit message against regular expression.
Following hook will fail commit if message doesn’t comply to Executable Book’s project commit message rules. The emoji part is skipped.
# FILE: .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: commit-message
name: check for commit message
language: pygrep
entry: '\A(BREAKING|NEW|IMPROVE|FIX|DOCS|MAINTAIN|TEST|RELEASE|UPGRADE|REFACTOR|DEPRECATE|MERGE|OTHER): .{1,72}(\n|\Z)'
args: [--negate, --multiline]
stages: [commit-msg]
Editorconfig¶
EditorConfig project consists of a file format for defining coding styles and a collection of text editor plugins that enable editors to read the file format and adhere to defined styles. EditorConfig files are easily readable and they work nicely with version control systems.
Here is sample .editorconfig file, based on Django’s .editorconfig, to start with.
# https://editorconfig.org/
root = true
[*]
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
charset = utf-8
# Docstrings and comments use max_line_length = 79
[*.py]
max_line_length = 119
# Use 2 spaces for the HTML files
[*.html]
indent_size = 2
# The JSON files contain newlines inconsistently
[*.json]
indent_size = 2
insert_final_newline = ignore
[**/admin/js/vendor/**]
indent_style = ignore
indent_size = ignore
# Minified JavaScript files shouldn't be changed
[**.min.js]
indent_style = ignore
insert_final_newline = ignore
# Makefiles always use tabs for indentation
[Makefile]
indent_style = tab
# Batch files use tabs for indentation
[*.bat]
indent_style = tab
[docs/**.txt]
max_line_length = 79
[*.yml]
indent_size = 2
[*.rst]
indent_size = 3
Plugins (see EditorConfig plugins download for full list):
Flake8¶
Flake8 combines pyflakes and pep8 (pep8 was renamed and is now pycodestyle to avoid confusion) into a single command.
Add Flake8 config into your tox.ini or setup.cfg:
[flake8]
exclude = build,.git,.tox,./tests/.env,**/migrations/*
ignore = W504,W601
max-line-length = 119
show-source = true
inline-quotes = single
docstring-quotes = double
example = lambda: 'example' # noqa: E731,E123
Further Flake8 reading:
Document autoformat¶
Frequently used Python document autoformatters are:
autopep8- autopep8black- blackyapf- Yet another Python formatter
VS Code Python autoformatting¶
Python extension for VS Code comes with autoformatting feature. You can format active document:
Keyboard shortcut Alt + Shift + F
Command palette: Ctrl + Shift + P >
>Format document
To select or change the formatting tool used:
Open settings using either method:
File > Preferences > Settings
Command palette Ctrl + Shift + P >
>Preferences: Open SettingsCtrl + ,
Navigate to
Extensions>PythonScroll to the Formatting: Provider
Select the formatter to be used, e.g.
yapf
There are also provider-specific settings which could be used to customize the formatting behavior.