Skip to content

What is PEP 8?

PEP 8 is Python’s style guide for writing readable, consistent code. This Python Enhancement Proposal defines conventions for the standard library that Python projects also use as a starting point.

Convention PEP 8 quick reference
Indentation Use 4 spaces per level; prefer spaces over tabs.
Naming Use snake_case for functions and variables, CapWords (also called PascalCase) for classes, and UPPER_CASE for constants.
Blank lines Separate top-level functions and classes with 2 blank lines; use 1 between methods inside a class.
Imports Put imports near the top, after module docstrings and before constants. Use separate lines for import os and import sys; group standard-library, third-party, and local imports with a blank line between groups.
Operator spacing Put spaces around assignment and comparisons (total = 3, total == 3); use spaces around the lowest-priority operators in mixed arithmetic (x*2 + y).
Line length Limit code to 79 characters; wrap flowing prose in comments and docstrings at 72.

Project-specific style guides take precedence over these recommendations. PEP 8 puts consistency within a project ahead of following every general convention, so an existing codebase’s style matters when deciding how to format a change.

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 Python rewrites names inside classes: __name becomes _ClassName__name
__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.

How PEP 8 changes the same code

Before, this code combines imports, uses mixed-case names, and crowds operators and arguments:

import sys, math
def CircleArea(Radius):
  area=math.pi*Radius**2
  print(area,file=sys.stdout)
  return area
def main():
  return CircleArea(3)

After, the same calculation uses separate imports, snake_case names, four-space indentation, and two blank lines between top-level definitions:

import math
import sys


def circle_area(radius):
    area = math.pi * radius**2
    print(area, file=sys.stdout)
    return area


def main():
    return circle_area(3)

Ruff’s formatter and Black fix indentation, blank lines, and spacing automatically, including the space after the comma. Ruff’s linter can split and sort these imports with its import rules enabled; neither formatter sorts imports or renames identifiers. Ruff’s naming rules can flag CircleArea and Radius, but updating the names and their uses requires a deliberate edit.

Where the 79-character limit comes from

PEP 8’s 79-character code limit supports viewing files side by side and working in tools that reserve a column at the edge of an 80-column window. Its 72-character limit applies to flowing prose in comments and docstrings.

Ruff and Black default to a line length of 88. That is a formatter policy rather than PEP 8’s limit, and neither formatter guarantees that every line will fit. PEP 8 also permits teams to agree on code lines up to 99 characters while keeping prose at 72.

When PEP 8 says to ignore its own rules

Readability and compatibility also matter. PEP 8 allows exceptions when applying a convention makes code harder to read, and warns against breaking backward compatibility just to satisfy the guide.

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.

Use tools to apply PEP 8 conventions

Ruff combines formatting with lint checks drawn from pycodestyle and other tools. The enabled rules determine which conventions it checks; formatting alone does not establish full PEP 8 compliance. See How to configure recommended Ruff defaults for configuration, or Set up Ruff for formatting and checking your code for a guided setup.

Last updated on