Flake8 is like lint and LEGO® bricks. A great combination.
You know the fuzzies that inevitably get intermixed with the bricks over time?
Those are not what I am writing about.
Flake8 is inherently modular, brick-like. A linter is a tool designed to hurt your feelings: it tells you when your code is malformed, even when the code itself executes fine.
With Flake8, you build the linting solution you desire, installing and configuring plugins accordingly.
This article chronicles the ever-evolving list of Flake8 tools and plugins I use to help keep Python code well-formed.
What Flake8 plugins or other tools do you use for linting Python? Comments are welcome.
Flake8 installation
Chances are your package manager has Flake8 available (as in dnf install python3-flake8
or apt install flake8
or brew install flake8
), or you could do something bold like sudo python3 -m pip install flake8
.
However, I strongly recommend installing Flake8 (or any Python packages) in a virtual environment instead. Feel free to read my article on Python virtual environments for an overview. (No need to read it all; just the venv
or virtualenv
or Poetry parts are an adequate introduction).
If you know that you want the same Flake8 available system-wide, not just in some virtual environments, then installing it with your package manager makes sense, or use pipx by installing pipx first, then using
pipx install flake8
. This will work fine on Windows, as well. You can also use pipx to install Flake8 plugins as inpipx install flake8-bugbear
. Again, not recommended, but I trust you know what you are doing.
If you have used venv
or virtualenv
to create a new virtual environment, then activate it first, then:
pip install flake8
If you would like to install all the plugins discussed in this article, you could instead:
pip install darglint flake8 flake8-bandit flake8-bugbear flake8-builtins flake8-comprehensions flake8-docstrings flake8-eradicate flake8-isort flake8-pytest-style flake8-spellcheck flakehell pep8-naming
Or you can download my requirements-flake8.txt
file and pip install -r requirements-flake8.txt
Or you could use Poetry instead:
poetry new --src lintingproject
cd lintingproject
poetry add darglint flake8 flake8-bandit flake8-bugbear flake8-builtins flake8-comprehensions flake8-docstrings flake8-eradicate flake8-isort flake8-pytest-style flake8-spellcheck flakehell pep8-naming
But I think that installing them all may be a bit ambitious. Why not instead review the list below, suggest some of your own, and we can all judiciously select the plugins that suit us? Brick by brick.
Running Flake8
To make Flake8 lint your code, run it from the command line, specifying the module, like this:
flake8 ./src/lintingproject/mymodule.py
or the whole package directory, like this:
flake8 ./src/lintingproject/
Using Poetry, you would try something like this:
poetry run flake8 ./src/lintingproject
Add some plugins to make it more interesting...
Flakehell
FlakeHell is not a Flake8 plugin, per se. It is a tool, a wrapper around Flake8. I like to use it because I can then configure Flake8 using a single centralized pyproject.toml
file, and because FlakeHell has pretty output.
See my write-up about FlakeHell if you are interested.
To run Flakehell, try something like
flakehell lint ./src/lintingproject/
Honestly, I am not sure why FlakeHell isn't more popular. Feel free to comment about why you hate, love, or ignore this tool.
flake8-bugbear
A longstanding and popular Flake8 plugin, flake8-bugbear brings together a variety of linting opinions sure to cause you constructive discomfort.
For instance, it will warn (with code B006
) if you set default function parameters that are mutable, as in def my_function(param1=[1,2,3])
instead of def my_function(param1=(1,2,3))
(lists are mutable, tuples are not).
See the list of warnings provided by this Swiss-army knife of plugins.
pep8-naming
Another plugin with a general assortment of warnings, pep8-naming looks to PEP 8 for code style guidance.
For example, it will warn if appropriate upper/lowercase guidelines are not followed, and if an instance method does not have self
as the first argument (shame on you for using s
, for instance). For the most part, this plugin makes me pay attention to case.
See the error codes for more detail.
flake8-builtins
I should have all the Python key words memorized, and I should carefully avoid using them in my own code. But, oh, the negligence. And the tears.
Thankfully, flake8-builtins happily slaps my wrists when I forget and use, for instance, list
as a variable name.
flake8-docstrings and Darglint
I admit: if I don't have an annoying robot reminding me to write docstrings, and write them well, I will blissfully write functions and modules without them.
That robot is formed by two tools: flake8-docstrings and Darglint.
Flake8-docstrings follows PEP 257 conventions and complains if you sidestep them. It can also be configured to insist on using Google's or Numpy's docstring style guides.
Darglint takes this one step further and will check your function arguments and return
statements, and make sure you have followed the guidance of Google or Numpy or even Sphinx and included the appropriately named documentation.
flake8-isort
I do love isort. This tool sorts your imports "so you don't have to," sorting alphabetically, and separating into sections and by type.
Need encouragement to get your import order right? The flake8-isort plugin will output warnings if the imports are not grouped, spaced, and ordered according to isort's configuration.
flake8-spellcheck
Note: flake8-spellcheck is more or less English only. If you want to use other human languages, skip this one or be prepared to add a lot of words to the allow list.
I love and hate the flake8-spellcheck plugin. It takes more of my attention than any other Flake8 plugin, because I am constantly needing to add words to the allowed spelling list.
That said, I enjoy the discipline. If I am using variable and module names (and words in comments) that are not actual words, can I really be confident that other developers (or me, a year later) will understand the code?
flake8-comprehensions
If list, dict, and set comprehensions aren't your thing, then skip this one (and ask yourself why you are not using these powerful Python features). But, wow, if they are, the flake8-comprehensions plugin is pure gold.
It will warn you if you are using one type of comprehension when another will do, or if you are using a generator when a comprehension will work.
See the list of warnings for a full explanation.
flake8-bandit
Bandit is a security audit tool for Python, flagging vulnerable code. Flake8-bandit connects this tool with Flake8.
See the list of Bandit test plugins to see what sorts of warnings you might expect.
flake8-eradicate
This one is a pain, but good.
Ever comment out code to disable it, but save it for later, as though version control weren't a thing? Of course, I tell myself, it is only temporary. Until a year and a half later I see the commented out code and wonder if:
- I forgot to delete it
- or forgot to re-enable it
Unsure? Yeah.
Eradicate is a tool that finds valid Python code in your comments. In other words, it roots out "dead code." Flake8-eradicate allows Flake8 to emit warnings when this dead code is found.
flake8-pytest-style
Pytest is a powerful and easy-to-use Python testing framework. Not surprisingly, there are good and not-so-good style choices that can be made with pytest tests.
Flake8-pytest-style ferrets out stylistic offenses in your pytest tests.
wemake-python-styleguide
I do not regularly use the wemake-python-styleguide as I end up spending an inordinate amount of time selectively disabling the warnings per line or per file of Python code.
That said, if you want to enter a very stylistically opinionated world for a time, to encourage greater finesse in your coding, it is a great tool. Think of it as a suite of Flake8 plugins. A suite that crashes down on you from lofty heights.
Configuring Flake8 and plugins
Flake8 has a powerful configuration mechanism, using .flake8
, setup.cfg
, or tox.ini
files. Plugins and warnings can be disabled per file (or even per line with # noqa
comments). See the configuration documentation for more info.
If you choose to use FlakeHell, it can be configured in pyproject.toml
. See FlakeHell's configuration docs for more info.
Other plugins?
Are there Flake8 plugins or other Python linting tools you use and recommend? Feel free to leave comments!
For inspiration, check out this curated awesome list.
Top comments (4)
Our team is switching from Nodejs to Python with a lot of new things to learn, so I liked the article!
We use Poetry and want to add static code analysis, but I'm not sure if I understand your suggestion to use Poetry for linting. Is the lintingproject meant to be an isolated tool environment or do you actually add the tools as project dependencies?
Great article! Learned a lot and will be adding a bunch of these plugins to my projects.
Thanks a lot, @bowmajd! 👍
You are welcome! I hope it is clear that I see wemake-python-styleguide as a very positive thing. What an impressive work, there! I just want to make sure people know what they are getting into... it is not for the faint of heart.
Seriously, I have learned some very good practices from it. I highly recommend the experience.