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

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.
- Indentation. Use 4 spaces per indentation level. Continuation lines either align with the opening bracket or use a "hanging indent" with nothing after the opening bracket on the first line. Details and examples are in our guide to indentation and line length.
- Tabs or spaces. Spaces are preferred; tabs only to stay consistent with code already indented with tabs. Python 3 refuses to run code that mixes them inconsistently.
- Maximum line length. 79 characters for code and 72 for long blocks of text such as comments and docstrings. Teams that agree on it may go up to 99 characters for code, provided comments and docstrings are still wrapped at 72.
- Line breaks and binary operators. Breaking before an operator is suggested for new code, following Donald Knuth's typesetting rule, but breaking after is allowed if done consistently.
- Blank lines. Two blank lines around top-level functions and classes, one around methods, and blank lines inside functions used sparingly to mark logical sections.
- Source file encoding. UTF-8, without an encoding declaration, in the core distribution.
- Imports. One module per
importline, at the top of the file, grouped as standard library, third party, then local, with a blank line between groups. PEP 8 also prefers absolute imports and discourages wildcard imports. - Module-level dunder names such as
__all__and__version__go after the module docstring and before other imports, exceptfrom __future__imports, which must come first.
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
- 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.tomlor a contributing guide. - 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.
- Keep review for what tools miss. Names, structure, comments and error handling deserve a human eye.
- 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
- Guido van Rossum, Barry Warsaw and Alyssa Coghlan, PEP 8 – Style Guide for Python Code, created 5 July 2001, consulted October 2026.
- David Goodger and Guido van Rossum, PEP 257 – Docstring Conventions, 2001.
- pycodestyle documentation, Introduction, disclaimer and error codes, and its changelog (version 2.0.0, 31 May 2016).
PEP 8, section by sectionIndentation and line length
Four spaces, no tabs, 79 characters: where these numbers come from, how to wrap long lines cleanly and which warnings point to each problem.
PEP 8, section by sectionNaming conventions
snake_case for functions, CapWords for classes, capitals for constants, and what one or two underscores really do, with the tools that check names.
Linters & formatterspycodestyle error codes
What E225, E302, E501 or W291 actually mean and how to fix each one: a family-by-family reference to the codes used by pycodestyle, flake8 and ruff.