PEP Process — Deep Dive

Historical context

The PEP process was established in 2000 by Barry Warsaw, inspired by the RFC process that built the internet and the Tcl Improvement Proposals. PEP 1, authored by Warsaw and Guido van Rossum, defines the process itself. Over 750 PEPs have been filed since then, documenting everything from major features to minor process tweaks.

Before PEPs, Python changes were discussed on the python-dev mailing list and approved by Guido’s personal judgement (the “Benevolent Dictator For Life” model). As the community grew, this informal process could not scale. PEPs provided structure without bureaucracy — a balance the community has maintained for over two decades.

The PEP repository and tooling

PEPs live at github.com/python/peps as reStructuredText files. The site peps.python.org renders them. The build system uses Sphinx with a custom theme.

PEP editors

PEP editors are volunteers who maintain the repository. Their responsibilities:

  • Verify PEP format compliance (PEP 12 template)
  • Assign PEP numbers
  • Update PEP statuses after Steering Council decisions
  • Merge editorial fixes

Editors do not judge technical merit. Their role is purely administrative.

PEP templates and tooling

# Clone and create a new PEP
git clone https://github.com/python/peps.git
cp pep-NNNN-template.rst pep-XXXX.rst
# Edit with your content
# Submit PR for number assignment

The template enforces a consistent structure: Preamble (metadata), Abstract, Motivation, Rationale, Specification, Backwards Compatibility, Security Implications, How to Teach This, Reference Implementation, Rejected Ideas, Open Issues, and Copyright.

Writing a PEP that succeeds

Pre-PEP strategy

Before writing a single line of the PEP, invest time in community alignment:

  1. Post on discuss.python.org (Ideas category). Gauge interest. If the response is overwhelmingly negative, save yourself the effort.
  2. Find a sponsor. Standards Track PEPs need a core developer sponsor who believes the idea is worth pursuing. They do not need to agree with every detail — just that the problem is real.
  3. Build a reference implementation. Nothing convinces like working code. A branch against CPython main that passes the test suite demonstrates feasibility and surfaces design issues early.

The Motivation section is everything

The Steering Council and community reviewers read dozens of PEPs. The ones that succeed have crystal-clear motivation:

Weak motivation: “It would be convenient to have syntax X.” Strong motivation: “Pattern Y appears in 47% of the top 1000 PyPI packages. Currently it requires N lines of boilerplate. Here are three real-world examples from Django, Flask, and NumPy where this causes bugs.”

PEP 634 (structural pattern matching) succeeded partly because it showed concrete, ugly workarounds in real-world code that the new syntax would eliminate.

Handling objections

Every PEP attracts objections. The Rejected Ideas section is your opportunity to show you have considered alternatives:

  • “Why not a library instead of a language feature?” — Explain why library-level solutions are insufficient.
  • “This adds complexity to the language.” — Acknowledge the cost and argue the benefit exceeds it.
  • “What about backwards compatibility?” — Provide a migration path and timeline.

PEP 572 (walrus operator) faced intense opposition. The PEP documented every major objection and the author’s response. This thoroughness contributed to its eventual acceptance.

Steering Council decision-making

How decisions happen

The Steering Council (five members, elected annually) discusses PEPs in private meetings and on the python-committers mailing list. Their decision criteria:

  1. Is the problem real and significant?
  2. Does the proposed solution fit Python’s design philosophy?
  3. Is the backwards-compatibility cost acceptable?
  4. Has the community had adequate time to discuss?
  5. Is there a working reference implementation?

Decisions are recorded as a Resolution in the PEP’s metadata:

Resolution: https://discuss.python.org/t/...

When the Council defers

For highly contentious PEPs, the Council may:

  • Request a longer discussion period
  • Ask for a revised PEP addressing specific concerns
  • Delegate the decision to a subject-matter expert (a “PEP delegate”)

PEP delegates are used for domain-specific proposals — e.g., a packaging expert might be delegated authority over a packaging PEP.

From acceptance to implementation

Implementation requirements

An accepted PEP must be implemented before the feature freeze of the target release. Key steps:

  1. CPython PR — The reference implementation becomes a real PR.
  2. DocumentationDoc/ updates showing the new feature with examples.
  3. What’s New — Entry in Doc/whatsnew/3.XX.rst.
  4. NEWS fragment — Via the blurb tool.
  5. Tests — Comprehensive test coverage in Lib/test/.

Feature flags and gradual rollout

Some PEPs introduce features behind __future__ imports:

from __future__ import annotations  # PEP 563

This allows the feature to exist in the language without changing default behaviour. After a deprecation period (typically two releases), the new behaviour becomes the default.

PEP 563 (postponed evaluation of annotations) used this mechanism but faced complications — the transition was delayed multiple times because downstream libraries (Pydantic, attrs) relied on runtime annotation evaluation.

Notable PEP case studies

PEP 8 — Style Guide (2001)

The most famous PEP. Originally descriptive (documenting existing conventions), it became prescriptive (the standard that linters enforce). PEP 8’s influence extends far beyond Python — many languages’ style guides cite it as inspiration.

PEP 484 — Type Hints (2014)

Introduced optional type annotations. The PEP was carefully designed to add no runtime overhead and no enforcement — purely optional metadata. This diplomatic approach avoided the “types vs. no types” war that fractured other communities.

PEP 703 — Making the GIL Optional (2023)

One of the most ambitious PEPs in Python’s history. Proposes making the Global Interpreter Lock optional via a build flag, enabling true multi-threaded parallelism. The implementation spans multiple releases (3.13+) and requires coordinating changes across the entire C extension ecosystem.

PEP 13 — Python Language Governance (2018)

Written after Guido stepped down, this PEP established the Steering Council model. It is a meta-PEP: a PEP about how PEPs are decided. The community voted on multiple governance proposals, and PEP 13 won.

The PEP ecosystem beyond CPython

The PEP model has been adopted by other projects:

  • DEP — Django Enhancement Proposals
  • NEP — NumPy Enhancement Proposals
  • SPEC — Scientific Python Ecosystem Coordination

These communities use PEPs as a template for their own governance, adapting the format to their needs.

Tradeoffs of the PEP process

StrengthLimitation
Ensures thorough design before implementationSlow — major features take years from idea to release
Creates permanent documentation of decisionsHigh barrier discourages small improvements
Democratic input from the communityDiscussions can become repetitive or hostile
Backwards-compatibility focus protects usersInnovation is sometimes blocked by conservatism

The process is intentionally conservative. Python’s stability is a feature, not a bug. Developers can trust that code written for Python 3.8 will mostly work on Python 3.13. That trust is built on the discipline of the PEP process.

One thing to remember: Every PEP, whether accepted or rejected, is a piece of Python’s design history. Reading them — especially the Motivation and Rejected Ideas sections — teaches you not just how Python works, but how programming language design decisions are made under real-world constraints.

pythongovernancecommunity

See Also

  • Python Contributing To Cpython Find out how everyday Python users can help build the language itself — no PhD required.
  • Python Python Enhancement Proposals History Travel through the story of Python's most important decisions — told through the documents that shaped the language.
  • Ci Cd Why big apps can ship updates every day without turning your phone into a glitchy mess — CI/CD is the behind-the-scenes quality gate and delivery truck.
  • Containerization Why does software that works on your computer break on everyone else's? Containers fix that — and they're why Netflix can deploy 100 updates a day without the site going down.
  • Python 310 New Features Python 3.10 gave programmers a shape-sorting machine, friendlier error messages, and cleaner ways to say 'this or that' in type hints.