Precommits workflow for Python¶
If you are experienced in python, then over time you might have realized the importance of linting. As your .py file grew in line, PEP8 standard went low.
So before we get started, lets understand few things for those who are new to python,
What is lint and linting?¶
In computer language, linter is any tool that detects and flags error in programming languages, including style errors.
Linting is running those tools against your source to check for above errors. It may or may not fix those issues.
Why to use it?¶
Can fix those errors automatically
It makes code more readable
It figures out error before runtime
Saves time
What is PEP8?¶
PEP8 is nothing but a style guide for python. It describes a standard, which includes indentation, function naming, variable naming, comparison, spacing, max line length, imports to name few. Since 2001, its like standard for every good python developer.
There are many python linters, autopep8, black, yapf, flake8. But for today we will be working with black and flake8.
What are hooks?¶
Hooks are additional code that you use to alter the behavior when some thing happens
We will be using gits pre commit hooks for linting our code with black and flake8 at staging, if they pass the test, then and only then we will be able to commit the files
Getting started¶
Lets install pre commit in our environment,
pip3 install pre-commit
Execute the following
pre-commit install
Create a pre-commit-config.yaml with hooks that you want. We will create a pre commit hook to use black to format my code and flake8 to check compliance with PEP8.
repos:
- repo: https://github.com/ambv/black
rev: stable
hooks:
- id: black
language_version: python3.6
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v1.2.3
hooks:
- id: flake8
Now for the code formatter black, it quite strict as compared to autopep8. Its not highly customizable. Though it still recommends 88 character code length. But we will keep it to 79.
Create pyproject.toml file at the same level .git folder
[tool.black]
line-length = 79
include = '\.pyi?$'
exclude = '''
/(
\.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
)/
'''
You can ofcourse customize it as you like
Now Flake8¶
Create a file for flake8 configuration
[flake8]
ignore = E203, E266, E501, W503, F403, F401
max-line-length = 79
max-complexity = 18
select = B,C,E,F,W,T4,B9
Those ignore values with E prefix are nothing but error codes to ignore
Results¶
Now when you run
git add some_file_txt.py
git commit -m "some usual commit"
Magic will happen and it will auto lint using black and flake will show error for unused variable, name etc.
You just have to fix the flake8 issues, black will do its job.
So again after fixing the issues, you will have to recommit the same files and black will pass. Flake8 might show some unfixed errors