Skip to content

What is PEP 8?

PEP 8 is a Python Enhancement Proposal that defines the style guide for the Python standard library, written by Guido van Rossum in 2001. Technically scoped to the standard library, it became the basis for code style conventions across the ecosystem.

What PEP 8 recommends for naming

Convention Use for
snake_case Functions, variables, module names
PascalCase Classes
UPPERCASE_WITH_UNDERSCORES Constants
_leading_underscore Internal-use names (convention only, not enforced by Python)
__double_leading_underscore Name mangling inside a class body
__dunder__ Python-reserved magic names (__init__, __str__, __len__)

A leading single underscore signals “internal” by convention. Python does not enforce it, but tools like Ruff can flag direct access to such names. Double underscores on both sides are reserved for Python itself; never invent new __dunder__ names.

What whitespace PEP 8 requires

  • 4 spaces for indentation (tabs prohibited)
  • Two blank lines between top-level functions and classes
  • One blank line between methods inside a class
  • Spaces around binary operators: x = x + 1, not x=x+1
  • A space after each comma, colon, and semicolon; no space before them
  • No trailing whitespace at the end of a line

Operator spacing has one notable exception: when combining operators of mixed precedence, PEP 8 recommends omitting spaces around lower-priority operators to show grouping (x*2 + y reads more clearly than x * 2 + y).

Where the 79-character limit comes from

PEP 8 sets a maximum of 79 characters for code and 72 for docstrings and comments. That limit reflects the 80-column terminal standard of the early 2000s. Modern formatters like Ruff and Black default to 88 characters, a pragmatic adjustment that has become the community norm.

When PEP 8 says to ignore its own rules

PEP 8 opens with a caveat: “A style guide is about consistency. Consistency within a project is more important. … know when to be inconsistent.” Two cases where intentional deviations are common:

  • Breaking a long import statement onto multiple lines is more readable than fitting it on one 79-character line with a backslash continuation.
  • Operator-aligned assignments in blocks of related constants can be clearer than strict PEP 8 spacing, even though the extra spaces technically violate it.

For intentional violations, # noqa: E501 (or the applicable rule code) tells Ruff and Flake8 to skip that line. See How to disable Ruff rules for a block of code for broader suppression patterns.

Enforcing PEP 8

Flake8 was the dominant PEP 8 linter for over a decade. Most projects have moved to Ruff, which handles both linting (catching PEP 8 violations via its pycodestyle rules) and formatting in a single tool, running faster than Flake8. See How to configure recommended Ruff defaults for setup, or How to replace Black, isort, Flake8, and pyupgrade with Ruff to consolidate an existing linting stack.

Last updated on