# flake8: Python Linter

Flake8 is a Python linting tool that wraps three checkers into one CLI: PyFlakes for logical errors, pycodestyle for [PEP 8](https://pydevtools.com/handbook/explanation/what-is-pep-8.md) style, and mccabe for cyclomatic complexity. A plugin system extends it with additional rules.

{{< callout type="info" >}}
[Ruff](https://pydevtools.com/handbook/reference/ruff.md) reimplements flake8's entire rule set with autofix support and 10-100x faster runs. Consider Ruff for new projects.
{{< /callout >}}

## When to use flake8

Flake8 fits codebases that already run it in CI and have tuned a stable configuration across `setup.cfg`, `tox.ini`, or `.flake8`. Teams that depend on flake8 plugins without Ruff equivalents, or that have built [pre-commit hooks](https://pydevtools.com/handbook/how-to/how-to-set-up-pre-commit-hooks-for-a-python-project.md) and editor integrations around its output, keep a familiar tool backed by a long-running ecosystem.

For new projects, [Ruff](https://pydevtools.com/handbook/reference/ruff.md) implements flake8's rule set (plus many popular plugins) with autofix support and faster runs. See [How do Ruff and Pylint compare?](https://pydevtools.com/handbook/explanation/how-do-ruff-and-pylint-compare.md) for an evaluation of the modern alternatives, or [How to replace Black, isort, flake8, and pyupgrade with Ruff](https://pydevtools.com/handbook/how-to/how-to-replace-black-isort-flake8-pyupgrade-with-ruff.md) for a step-by-step migration that maps each flake8 plugin to its Ruff prefix.

## Key Features

### Code analysis

Flake8 delegates error detection to PyFlakes, which flags undefined names, unused imports, redefined-but-unused variables, and other logical problems without executing the code. The mccabe checker reports functions whose cyclomatic complexity exceeds a configurable threshold.

### Style enforcement

The pycodestyle checker validates PEP 8 compliance: line length, whitespace around operators, blank-line conventions, and import ordering. Each violation gets a code (e.g. `E501` for long lines, `W291` for trailing whitespace) that can be individually suppressed or enforced.

### Configuration

Flake8 reads configuration from `setup.cfg`, `tox.ini`, or a dedicated `.flake8` file. It does not natively read [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md). Rules can be toggled globally with `--select` and `--ignore`, or suppressed per line with `# noqa: E501`.

### Plugins

A plugin ecosystem adds checks beyond the built-in set. Popular plugins include `flake8-bugbear` (additional opinionated warnings), `flake8-import-order`, and `flake8-docstrings`. Ruff reimplements most of these as built-in rule prefixes, which is one of the main reasons projects migrate.

## Pros

- Combined PyFlakes, pycodestyle, and mccabe checks in a single invocation
- Large plugin ecosystem for specialized rules
- Per-line suppression with `# noqa` codes
- Stable rule codes that have not changed in years

## Cons

- No autofix: reports problems but does not rewrite code
- 10-100x slower than Ruff on large codebases
- No native pyproject.toml support
- No formatting capabilities (requires pairing with [Black](https://pydevtools.com/handbook/reference/black.md) or Ruff)

## Learn More

- [How do Ruff and Pylint compare?](https://pydevtools.com/handbook/explanation/how-do-ruff-and-pylint-compare.md)
- [How to replace Black, isort, flake8, and pyupgrade with Ruff](https://pydevtools.com/handbook/how-to/how-to-replace-black-isort-flake8-pyupgrade-with-ruff.md)
- [Set up Ruff for formatting and checking your code](https://pydevtools.com/handbook/tutorial/set-up-ruff-for-formatting-and-checking-your-code.md) (Tutorial)
- [Flake8 documentation](https://flake8.pycqa.org/)
- [Flake8 configuration guide](https://flake8.pycqa.org/en/latest/user/configuration.html)
- [Flake8 on GitHub](https://github.com/PyCQA/flake8)
