| name | python-pep |
| description | Write a Python Enhancement Proposal (PEP) — a formal design document proposing a change to the Python language, standard library, or process, with the canonical RFC822 header preamble plus Abstract, Motivation, Rationale, Specification, Backwards Compatibility, Security Implications, How to Teach This, Reference Implementation, Rejected Ideas, and Open Issues. Use when the user is proposing or drafting a Python language/stdlib/process change in PEP form. Anti-trigger; for a project's own architecture decision use an ADR skill, and for end-user task instructions use a how-to. |
| argument-hint | <the proposed Python change> |
python-pep
Produces a Python Enhancement Proposal: the standardized design document the
CPython community uses to propose and record changes. A PEP argues a change on
its merits, specifies it precisely enough to implement, and survives review by
the Steering Council or a delegate. It is not a tutorial, a changelog, or a
bug report — it is a durable, reviewable design record.
The three PEP types
- Standards Track — a new feature or implementation change to Python (the
language, the C API, or the standard library). Most PEPs are this type.
- Informational — design guidance, conventions, or community information
that does not propose a new feature (e.g. the release schedule).
- Process — a change to a process around Python (decision-making,
governance, tooling) rather than the language itself.
Status lifecycle
Draft ──> Accepted ──> Final
│ │
├─> Rejected (turned down on its merits)
├─> Withdrawn (the author abandons it)
├─> Deferred (no champion / not ready)
└─> Superseded (replaced by a later PEP)
- A PEP opens as Draft. Standards Track PEPs may pass through
Provisional/Accepted before reaching Final once the reference
implementation lands.
- Rejected, Withdrawn, and Deferred are terminal-for-now outcomes;
Superseded points forward to the PEP that replaced it.
- The header's
Status: field always reflects exactly one of these states at
a time — a PEP is never simultaneously Draft and Rejected, or Accepted and
Superseded. State this single-state constraint explicitly any time you
discuss, review, or recommend a Status: value — don't let it stay implicit
just because it's obvious to you; the reader needs it spelled out too.
Pattern (industry: PEP 1 / PEP 12)
- Header preamble — an RFC822-style block:
PEP, Title, Author,
Status, Type (one of the three above), Created, and — for Standards
Track — Python-Version.
- Abstract — a short (≈200 word) description of the proposal.
- Motivation — why the status quo is insufficient; the problem being solved.
- Rationale — why this design, and how it compares to alternatives.
- Specification — the normative, implementable detail of the change.
- Backwards Compatibility — what breaks, and the migration story. Required.
- Security Implications — attack surface and risks, or an explicit "none".
- How to Teach This — how the change is explained to new and existing users.
- Reference Implementation — link to (or inline) working code; required
before a Standards Track PEP can be marked Final.
- Rejected Ideas — alternatives considered and why they were dropped.
- Open Issues — unresolved questions still under discussion.
Authoring rules
- One PEP, one proposal. Keep scope narrow enough to accept or reject as a unit.
- The Specification must be precise enough that two implementers produce the same
behavior. Defer rationale and persuasion to their own sections.
- Never omit Backwards Compatibility or Rejected Ideas — reviewers read those
first. "None" is an acceptable answer; silence is not.
- Address the reader as the Steering Council: state the change, then defend it.
Reviewing an existing draft
When asked to review, critique, or give feedback on a draft PEP (rather than
author one from scratch), a list of named gaps is not a review — it's a todo
list the author still has to solve alone. For every gap you flag, also supply
the concrete text that fills it, not just an instruction to fill it:
- Header problems: write out a corrected header block (or the corrected
line) with real values, e.g.
Status: Draft instead of "fix the Status
field to a valid lifecycle state."
- Missing or empty required sections (Backwards Compatibility, Security
Implications, Rejected Ideas, etc.): draft the actual replacement text —
even a short paragraph or a one-line "None: this change touches no public
API" — not just "add a Backwards Compatibility section."
- Vague or unspecified prose: rewrite the offending sentence or paragraph
as it should read, inline or as a suggested replacement block, not merely a
description of what's wrong with it.
Naming a gap tells the author what's missing; drafting the fix tells them what
"done" looks like and saves a review round-trip. Include both in every review
output — the diagnosis and the corrected text — never the diagnosis alone.
MIF frontmatter
type: semantic — a PEP is declarative design knowledge, not a time-bound log
or a how-to. Climb to L2 with namespace (e.g. pep/standards-track), tags,
and title when known. Gate every output with mif-validate --level 1.
Why machine-readable
The frontmatter lets an agent answer questions about a PEP without parsing the
prose: is this proposal still current, where did it come from, what backs the
design, and which other PEPs does it touch. The L1 floor carries none of that —
to a machine it is opaque text. The climb adds the answers as structured fields:
- L1 floor —
id, type, created + body. A complete PEP, but opaque to a
machine. See templates/good-l1.md.
- L3 (the highest this genre honestly supports) — adds
modified,
temporal (validity window + ttl), provenance (source + trust), typed
citations[], and a relationships[] link. See templates/good.md, which
gates at mif-validate --level 3.
See templates/good.md (a conformant Standards Track PEP at L3),
templates/good-l1.md (the same PEP at the L1 floor), and templates/bad.md
(a PEP with a malformed header and missing required sections — the most common
review-blocking errors).