• pyflakes – checks only obvious bugs and never code style. There are no opinionated checks. Pyflakes should be enabled in any project, and all errors must be fixed.
  • pycodestyle – most important code style checker. Controls compatibility with PEP-8 that is standard de-facto for how Python code should look like. Initially, the tool was called pep8, but renamed after Guido’s request.
  • flake8 is the most famous Python linter. First of all, it is a framework allowing you to write custom linters that can be configured and run in a unified way. Pyflakes and pycodestyle are default dependencies of Flake8. If you just install and run Flake8 in a clean environment, you’ll see their checks.
  • flakehell is a wrapper around flake8. It provides additional commands and features, nicer output, and more control over plugins and checks.
  • PyLint is an alternative linter with many checks that are missed in flake8 plugins. Some of them are opinionated and can be difficult to satisfy. However, most of the checks are useful. FlakeHell supports PyLint as a plugin. The important thing to remember is that PyLint is slow because of heavy inference of types and values.
  • wemake-python-styleguide is a flake8/flakehell plugin, providing a lot of checks. It is fast, strict, and helpful, finds many bugs, style issues, enforces consistency. It is very opinionated, so you probably want to disable some (most of the) checks.

See awesome-flake8-extensions for more plugins.

Type annotations

Python is a dynamically typed language. It makes development (and especially rapid prototyping) fast and easy but can complicate maintenance and lead to unexpected bugs in production. The solution is to add type annotations that can be later statically analyzed. In short, it is great, and you should give it a try. I won’t dive deep into this topic here. Instead, there are a few helpful links to get started with type annotations:


Python has quite a few code formatters with different code style and philosophy behind.

There are 3 all-in-one code formatters, all of them are supported by VSCode out of the box:

  • autopep8 is the oldest and the least opinionated Python code formatter. It formats the code to follow PEP-8 and nothing else. Under the hood, it uses the mentioned above pycodestyle. So, if the project passes pycodestyle (or flake8) checks, you can safely use autopep8.
  • black is “uncompromising” and opinionated code formatter. The code style is close to PEP-8 (there are few exceptions) but also it has an opinion about pretty much everything. It has some issues that make it a bad choice for an experienced team. However, it can be a good choice for an inexperienced team, an open-source project, or for quick formatting of an old and dirty code. See Don’t use Black in your team for more information.
  • yapf is a code formatter from Google. Like black, it reformats everything. The main difference is that every small detail in yapf is configurable. It makes sense to use yapf for a project with a code style that is different from PEP-8. However, if you have a choice, prefer using PEP-8 for all projects.

A few small but helpful formatters:

  • isort groups and sorts imports. Usually, the imports section in Python is quite messy, and isort brings an order here. It is a powerful tool and every stylistic decision there can be configured. Use isort.
  • add-trailing-comma adds trailing commas to multiline function calls, function signatures, and literals. Also, it fixes indentation for closing braces.
  • autoflake removes unused imports and variables. It helps clean up a messed code.
  • docformatter formats docstrings according to PEP-257.
  • pyupgrade changes the code to use newer Python features. It will replace old comprehensions style, old formatting via %, drop Unicode and long literals, simplify super calls, and much more.
  • unify formats string literals to use one style of quotes (single or double).

See awesome-python-code-formatters for more tools.


  • Flake8 is famous and has integration (or a hacky described somewhere way to integrate) with everything.
  • FlakeHell can pretend to be flake8 for integrations
  • VSCode Python extension supports flake8, pylint, isort, autopep8, black, and yapf out of the box. Just select what you want to use.
  • To integrate something else, like a less popular code formatter, use pre-commit.