The Best flake8 Extensions for your Python Project
In the last blog post about coding style, we dissected what the state of the art was regarding coding style check in Python.
As we've seen, Flake8 is a wrapper around several tools and is extensible via plugins: meaning that you can add your own checks. I'm a heavy user of Flake8 and relies on a few plugins to extend the check coverage of common programming mistakes in Python. Here's the list of the ones I can't work without. As a bonus, you'll find at the end of this post, a sample of my go-to
The name is quite explicit: this extension checks the order of your
import statements at the beginning of your files. By default, it uses a style that I enjoy, which looks like:
import os import sys import requests import yaml import myproject from myproject.utils import somemodule
The builtin modules are grouped as the first ones. Then comes a group for each third-party modules that are imported. Finally, the last group manages the modules of the current project. I find this way of organizing modules import quite clear and easy to read.
To make sure flake8-import-order knows about the name of your project module name, you need to specify it in
tox.ini with the
If you beg to differ, you can use any of the other styles that flake8-import-order offers by default by setting the
import-order-style option. You can obviously provide your own style.
The flake8-blind-except extension checks that no
except statement is used without specifying an exception type. The following excerpt is, therefore, considered invalid:
try: do_something() except: pass
except without any exception type specified is considered bad practice as it might catch unwanted exceptions. It forces the developer to think about what kind of errors might happen and should really be caught.
In the rare case any exception should be caught, it's still possible to use
except Exception anyway.
The flake8-builtins plugin checks that there is no name collision between your code and the Python builtin variables.
For example, this code would trigger an error:
def first(list): return list
list is a builtin in Python (to create a list!), shadowing its definition by using
list as the name of a parameter in a function signature would trigger a warning from flake8-builtins.
While the code is valid, it's a bad habit to override Python builtins functions. It might lead to tricky errors; in the above example, if you ever need to call
list(), you won't be able to.
This module is handy as it is still slapping my fingers once in a while. When using the
logging module, it prevents from writing this kind of code:
mylogger.info("Hello %s" % mystring)
While this works, it's suboptimal as it forces the string interpolation. If the logger is configured to print only messages with a logging level of warning or above, doing a string interpolation here is pointless.
Therefore, one should instead write:
mylogger.info("Hello %s", mystring)
Same goes if you use
format to do any formatting.
Be aware that contrary to other flake8 modules, this one does not enable the check by default. You'll need to add
enable-extensions=G in your
The flake8-docstrings module checks the content of your Python docstrings for respect of the PEP 257. This PEP is full of small details about formatting your docstrings the right way, which is something you wouldn't be able to do without such a tool. A simple example would be:
class Foobar: """A foobar"""
While this seems valid, there is a missing point at the end of the docstring.
Trust me, especially if you are writing a library that is consumed by other developers, this is a must-have.
This extension is a good complement to flake8-docstrings: it checks that the content of your docstrings is valid RST. It's a no-brainer, so I'd install it without question. Again, if your project exports a documented API that is built with Sphinx, this is a must-have.
My standard tox.ini
Here's the standard
tox.ini excerpt that I use in most of my projects. You can copy paste it and use
[testenv:pep8] deps = flake8 flake8-import-order flake8-blind-except flake8-builtins flake8-docstrings flake8-rst-docstrings flake8-logging-format commands = flake8 [flake8] exclude = .tox # If you need to ignore some error codes in the whole source code # you can write them here # ignore = D100,D101 show-source = true enable-extensions=G application-import-names = <myprojectname>
Before disabling an error code for your entire project, remember that you can force flake8 to ignore a particular instance of the error by adding the
# noqa tag at the end of the line.
If you have any flake8 extension that you think is useful, please let me know in the comment section!