PEP 8, section by section

PEP 8 Explained: The Python Style Guide, Section by Section

PEP 8, section by section · · Published 2026-10-27

A long workshop hall filled with rows of nineteenth-century printing presses and their levers
Printing presses at the Bureau of Engraving and Printing, Washington. Photograph attributed to Mathew B. Brady, US National Archives, public domain.

PEP 8 is the document most Python developers mean when they say "Python style". It is often treated as a list of rules that a linter enforces, but it reads more like a style manual: some recommendations are precise, some are explicitly left to judgment, and the opening section tells you when to ignore it. This guide walks through it in the order the document itself uses.

Why a style guide at all

PEP stands for Python Enhancement Proposal. Most PEPs propose language features; PEP 8 is a "Process" PEP with the status "Active", which means it is a living document rather than a feature that was accepted once and frozen. Its introduction says it gives "coding conventions for the Python code comprising the standard library in the main Python distribution", and that it evolves "as additional conventions are identified and past conventions are rendered obsolete by changes in the language itself".

The section that follows, titled "A Foolish Consistency is the Hobgoblin of Little Minds", is the one most worth reading in full. It starts from one of Guido van Rossum's key insights: code is read much more often than it is written. A shared style means a reader can spend attention on what the code does rather than on how it is laid out. The same section then sets the order of priorities: consistency with the guide is important, consistency within a project is more important, and consistency within one module or function is the most important.

PEP 8 also lists good reasons to ignore a guideline: when applying it would make the code less readable, to stay consistent with surrounding code, because the code predates the guideline and there is no other reason to touch it, or to remain compatible with older Python versions. It also gives a direct warning: do not break backwards compatibility just to comply with PEP 8.

Code layout

The longest part of the guide covers how code sits on the page.

Here is a short module that follows these layout rules:

"""Small helpers for reading configuration files."""

import json
from pathlib import Path

DEFAULT_NAME = "settings.json"


def load_settings(folder, name=DEFAULT_NAME):
    """Return the settings stored in folder/name as a dict."""
    path = Path(folder) / name
    with path.open(encoding="utf-8") as handle:
        return json.load(handle)


class Settings:
    """Read-only access to a settings dictionary."""

    def __init__(self, data):
        self._data = dict(data)

    def get(self, key, default=None):
        return self._data.get(key, default)

String quotes

PEP 8 makes no recommendation between single and double quotes: pick one and stick to it, and use the other kind when a string contains a quote character, to avoid backslashes. For triple-quoted strings it asks for double quotes, to match the docstring convention of PEP 257. Formatters have filled this gap in practice: black, for instance, normalises to double quotes by default.

Whitespace in expressions and statements

This section lists "pet peeves": spaces just inside brackets, before a comma or colon, before the parenthesis of a call or the bracket of an index, and extra spaces used to align assignments. It then recommends a single space around assignment, augmented assignment, comparisons and Boolean operators, and allows dropping spaces around higher-priority arithmetic operators to show grouping (x = x*2 - 1). Keyword arguments and unannotated defaults take no spaces around =; annotated defaults do. Most of these cases are checked automatically by linters.

Trailing commas

A trailing comma is mandatory for a one-element tuple, and PEP 8 suggests wrapping it in parentheses for clarity: FILES = ('setup.cfg',). Otherwise trailing commas are optional, but useful when a list of values, arguments or imports is expected to grow: put each item on its own line, end every line with a comma, and put the closing bracket on the next line. Version control diffs then show one changed line per added item.

Comments and documentation strings

The comments section opens with a line every reviewer should know: "Comments that contradict the code are worse than no comments." Comments should be complete sentences, block comments are indented to the level of the code they describe, and inline comments should be rare, separated from the code by at least two spaces, and should not state the obvious. Docstrings are delegated to PEP 257, with two reminders: write them for all public modules, functions, classes and methods, and put the closing quotes of a multi-line docstring on a line of their own.

Naming conventions

PEP 8 admits that "the naming conventions of Python's library are a bit of a mess". It distinguishes descriptive naming styles (lowercase, CapWords, UPPER_CASE and so on) from prescriptive rules: modules short and lowercase, classes in CapWords, functions and variables in lowercase with underscores, constants in capitals, exceptions ending in "Error" when they are errors, self and cls as first arguments. It also explains leading and trailing underscores, and asks you never to use l, O or I as single-character names. All of this is detailed in our naming conventions guide. The section closes with advice on public and internal interfaces, including declaring a module's public API in __all__.

Programming recommendations

The last major section is less about appearance and more about habits that avoid bugs: compare to None with is, use is not rather than not ... is, use def rather than assigning a lambda, catch specific exceptions rather than using a bare except:, keep try blocks small, be consistent in return statements, use startswith() and isinstance(), and rely on the truthiness of empty sequences. It ends with style rules for function and variable annotations. Several of them are checked by pycodestyle (E711, E712, E713, E721, E722, E731).

What a tool can check, and what it cannot

A large part of PEP 8 is mechanical, and that is where tools help. pycodestyle, the checker that was called pep8 until its version 2.0.0 in 2016, reports most layout and whitespace issues with codes such as E302 or E501 (see our list of pycodestyle codes). flake8 and ruff include those checks alongside others, pylint adds its own conventions, and formatters such as black and ruff's formatter rewrite the layout so that most whitespace questions never reach a reviewer.

pycodestyle's own documentation is candid about the limits: it "does not enforce every single rule of PEP 8", naming conventions are left to plugins, and docstring conventions are out of its scope. Some recommendations, like writing comments in complete sentences or choosing names that reflect usage rather than implementation, cannot be expressed as an algorithm at all. The checker on our home page covers a documented subset of pycodestyle's rules for quick checks in the browser.

How to use PEP 8 in a project

  1. Decide what "our style" means. Most projects adopt PEP 8 plus a formatter's choices (line length, quotes) and write the exceptions down in the repository, usually in pyproject.toml or a contributing guide.
  2. Automate the mechanical parts. Run a formatter and a linter in the editor, in a pre-commit hook and in continuous integration, so that style is settled before review.
  3. Keep review for what tools miss. Names, structure, comments and error handling deserve a human eye.
  4. Do not reformat history for its own sake. PEP 8 itself warns against breaking compatibility for style; when you do apply a formatter to old code, do it in a separate commit.

Sources