Linting Python at GDS
This manual advises the use of the Flake8 all in one lint, codestyle and complexity checker.
What is Flake8?
Flake8 is a command line utility that acts as a drop in replacement for the pep8/pycodestyle command line checker. It includes pep8/pycodestyle checks as well as adding complexity checks, and linting. If you’re already using the pep8/pycodestylechecker you’re most of the way there. If not then, never fear. You’ll find everything you need on this page.
How to use Flake8
Implementation of Flake8 will depend on whether the repository you want to run the checks on is a module or an application, and how your dependencies and automated test ci is set up.
For a quick example run the below code (assuming you have
mkdir flake8_test; echo 'import os' > flake8_test/flake8_test_file.py python3 -m venv flake8_test/venv source flake8_test/venv/bin/activate pip install flake8 flake8 flake8_test/flake8_test_file.py deactivate rm -rf flake8_test
The last line of output should read:
> flake8_test/flake8_test_file.py:1:1: F401 'os' imported but unused
Pyflakes catches a linting error:
F401 '<module>' imported but unused
This is because our file imports the
os module but never uses it.
Unused imports are considered a bad thing because they pollute the namespace, increasing the number of names a
developer needs to keep track of.
Unused imports are a fairly simple example but errors like
F811 redefinition of unused <name> from line <N>
F841 local variable <name> is assigned to but never used can indicate that there are real problems with the code, and that it may not be acting as expected.
For a full list of error codes check out:
Flake8 has been designed to be extensible and as such has spawned numerous plugins. They’re worth a look to see if any would be particularly beneficial to your code base.
Examples include checks for requiring copyright/licensing strings, requiring docstrings or warnings for upcoming deprecations.
A list can be found by performing a PyPI search.
Flake8 per file ignores
A particularly useful feature of Flake8 is the ability to specify rule exemptions on a per directory, per file, or per regex match basis.
Commonly it’s used for ignoring unused imports in module level
files or imports not being at the top of a file in settings files or scripts.
Commonly a configuration file will live in the root of the package. By default Flake8 will look for a
.flake8 file in each directory.
[flake8] # Rule definitions: http://flake8.pycqa.org/en/latest/user/error-codes.html # D203: 1 blank line required before class docstring # W503: line break before binary operator exclude = venv*,__pycache__,node_modules,bower_components,migrations ignore = D203,W503 max-complexity = 9 max-line-length = 120
In the above file we exclude directories we want the checker to ignore completely, ignore specific rules we disagree with, set the maximum line length and set the maximum complexity. We’ve also included comments detailing what the specific exclusions are.
Note: you can also ignore rules on particular lines of code or files by adding a
# noqa comment - see flake8’s noqa syntax.