Useful Flake8 Plugins for Python Linting
Tags: python, flake8, linting
Published: 2020-08-30 01:16:41

[Flake8] is like lint and LEGO® bricks. A great combination.

![Picture of LEGO bricks](https://dev-to-uploads.s3.amazonaws.com/i/4cranixwcg87bypbmn1z.jpg)

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](https://en.wikipedia.org/wiki/Lint_(software)) 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](https://dev.to/bowmanjd/python-tools-for-managing-virtual-environments-3bko) 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](https://dev.to/bowmanjd/how-do-i-install-a-python-command-line-tool-or-script-hint-pipx-3i2) 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 in `pipx 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](https://dev.to/bowmanjd/python-tools-for-managing-virtual-environments-3bko#venv-activate) first, then:

```console
pip install flake8
```

If you would like to install all the plugins discussed in this article, you could instead:

```console
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][requirements] and `pip install -r requirements-flake8.txt`

Or you could [use Poetry instead](https://dev.to/bowmanjd/getting-started-with-python-poetry-3ica):

```console
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:

```console
flake8 ./src/lintingproject/mymodule.py
```

or the whole package directory, like this: 

```console
flake8 ./src/lintingproject/
```

Using Poetry, you would try something like this:

```console
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][FlakeHellArticle] if you are interested.

To run Flakehell, try something like

```console
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](https://github.com/PyCQA/flake8-bugbear#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](https://www.python.org/dev/peps/pep-0008/) 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](https://github.com/PyCQA/pep8-naming#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](https://www.python.org/dev/peps/pep-0257/) and complains if you sidestep them. It can also be configured to insist on using [Google's](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) or [Numpy's](https://numpydoc.readthedocs.io/en/latest/format.html) 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](https://sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html#the-sphinx-docstring-format) and included the appropriately named documentation.

## [flake8-isort]

I do love [isort](https://pycqa.github.io/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](https://docs.python.org/3/tutorial/datastructures.html#list-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](https://github.com/adamchainz/flake8-comprehensions#rules) for a full explanation.

## [flake8-bandit]

[Bandit](https://github.com/PyCQA/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](https://bandit.readthedocs.io/en/latest/plugins/index.html#complete-test-plugin-listing) 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](https://github.com/myint/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](https://docs.pytest.org/) 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](https://flake8.pycqa.org/en/latest/user/configuration.html) for more info.

If you choose to use [FlakeHell], it can be configured in `pyproject.toml`. See [FlakeHell's configuration docs](https://flakehell.readthedocs.io/config.html) 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](https://github.com/DmytroLitvinov/awesome-flake8-extensions).

[requirements]: https://gist.github.com/bowmanjd/a0d2f9295402fcf5a5ef17db731fec0e
[flake8]: https://flake8.pycqa.org/
[flakehelldocs]: https://flakehell.readthedocs.io/
[Python]: https://python.org
[FlakeHellArticle]: https://dev.to/bowmanjd/using-flake8-and-pyproject-toml-with-flakehell-1cn1
[FlakeHell]: https://github.com/life4/flakehell
[darglint]: https://github.com/terrencepreilly/darglint
[flake8-bandit]: https://github.com/tylerwince/flake8-bandit
[flake8-bugbear]: https://github.com/PyCQA/flake8-bugbear
[flake8-builtins]: https://github.com/gforcada/flake8-builtins
[flake8-comprehensions]: https://github.com/adamchainz/flake8-comprehensions
[flake8-docstrings]: https://gitlab.com/pycqa/flake8-docstrings
[flake8-eradicate]: https://github.com/sobolevn/flake8-eradicate
[flake8-isort]: https://github.com/gforcada/flake8-isort
[flake8-mutable]: https://github.com/ebeweber/flake8-mutable
[flake8-pytest-style]: https://pypi.org/project/flake8-pytest-style/
[flake8-spellcheck]: https://github.com/MichaelAquilina/flake8-spellcheck
[pep8-naming]: https://github.com/PyCQA/pep8-naming
[wemake-python-styleguide]: https://github.com/wemake-services/wemake-python-styleguide