Summary

  • Python’s PEP process separates community discussion, a Steering Council or approved PEP-Delegate resolution, completion of a reference implementation, incorporation into the main source repository and the later controls of a release branch.
  • A decision-to-release receipt should fix the proposal, the authorised decision-maker, the resolution, the implementation revision, target branch, release stage and artifact instead of translating every “accepted” label into a release claim.

One language, several decisions

“Python accepted it” is efficient shorthand, but it can obscure the part that matters to a maintainer, a downstream distributor or a team deciding when to rely on a change. Does the sentence mean that an idea received a PEP number? That a proposal has a published resolution? That an approved delegate exercised authority for that proposal? That a reference implementation is complete? That code is in the branch being stabilized? Or that a release manager cut a final artifact?

PEP 1 makes the distinctions unusually visible. A PEP is a design document: a way to present a feature or process change, collect public input and preserve the reasoning and dissent around a decision. Its author must build consensus and document disagreement. That work is evidence for a decision. It is not itself the decision, and it is certainly not a delivery receipt for a particular runtime.

The useful question is therefore not who said something first or loudest. It is what action was authorised, by whom, under which published rule, concerning which stable proposal or artifact. Participation, review, delegated judgement, a repository change and release operations have different purposes. A record that collapses them borrows authority from the next stage before the evidence for that stage exists.

A PEP document is not a decision by itself

PEP editors handle the administrative and editorial side of the workflow. A number can be assigned and a draft can be committed after that review. PEP 1 is explicit that editorial approval is not the same as acceptance of the PEP. The distinction is valuable precisely because a clean, accessible document can invite serious technical work without pretending that its design is already binding.

Discussion has a similarly bounded role. Authors gather feedback in public venues; the current discussion link lets interested contributors inspect the evolving proposal and the objections that matter to it. A long thread can demonstrate that a design was tested in public. It cannot, by volume alone, tell a reader which authority issued the resolution. Attendance is evidence of participation. It is not a substitute for an identified decision path.

This is not a dismissal of consensus. Python’s rules seek it because it exposes implementation concerns before they become lock-in. The mistake begins when consensus becomes a floating word used to imply Council action, delegate authority, a completed implementation and a scheduled release at once. The first three may occur at different times; the fourth may never follow on the timeline assumed by a reader.

Delegation narrows a decision; it does not multiply it

Under PEP 1, final authority for PEP approval remains with the elected Steering Council. A core developer who considers themselves suitably experienced may offer to serve as PEP-Delegate for a particular proposal. If the Council approves that offer, the delegate has authority to approve or reject that PEP. Community members may also bring concerns about the delegate’s suitability back to the Council.

This arrangement is neither a return to a universal individual ruler nor a ritual designed to make the Council irrelevant. It is a bounded delegation. It makes a decision possible near the technical context while preserving a public route for appointment, concern and ultimate responsibility. The scope is the designated PEP, not all language design, all repositories or all future releases.

PEP 13 supplies the outer frame. The five-person Steering Council has broad authority, is asked to seek consensus before formal action, may delegate parts of its authority and serves as a court of final appeal when other methods fail. That broad authority is meaningful only when it remains attributable. A Council’s existence cannot be pasted onto every commit or schedule; a delegate’s name cannot be treated as a general project mandate.

For a disputed or consequential proposal, a trustworthy public account should name the PEP, decision state, relevant resolution record, the decision-maker’s role and the delegation when one exists. “Python decided” is not false when the process has resolved a PEP; it is just too incomplete to carry the full operational claim by itself.

Accepted, Final and released answer different questions

PEP 1 establishes a critical boundary: after a PEP is accepted, its reference implementation must be completed and incorporated into the main source repository before the status becomes Final. An accepted design is therefore not proof that the implementation is complete. Final is not merely a ceremonial synonym for an earlier decision; it joins the decision record to a completed reference implementation in the designated repository.

The rule contains another warning against simple status storytelling. A provisionally accepted PEP may still be rejected or withdrawn even after related changes have appeared in a Python release. Readers should not use a status word as a universal warranty about permanence, downstream compatibility or the absence of future redesign. A process label has the force given by its rule, not the force a product announcement wishes it had.

Nor does a main-branch merge automatically establish a release. CPython’s development guidance describes different branches and stages for different jobs. Feature work occurs on the in-development branch. At beta, a maintenance branch is created so the next cycle can proceed on main while the current cycle is stabilized. At release candidate stage, proposed code changes are restricted to reviewed bug fixes serious enough for the final window. When a final release is cut, only the release manager may change that branch.

The point is operational rather than ceremonial. A release manager’s limited control at the final cut protects a specific stabilization surface. It does not retroactively decide the design rationale of every PEP. Conversely, a valid PEP decision does not give a proposal author, a delegate or a casual reader authority to declare a branch ready. The decision surface and the release surface meet, but they should not be fused.

Keep a decision-to-release receipt

For a PEP resolution, the receipt should preserve the proposal number and version, canonical discussion, decision-maker, delegation or Council path, resolution record, status and any explicitly documented scope. It should say what the resolution did not settle as well: target version, implementation completion, backports and delivery dates where those are not part of the resolution.

For implementation, it should add the reference revision, repository, target branch, tests or review records that are public, and the relationship to the PEP. It should not convert a code reference into proof of operational adoption. For release, it should add the branch, stage, artifact identifier, release-manager act and published version. A final binary, source archive or tag deserves its own stable identifier rather than an inference from a discussion date.

This is not a request to turn Python’s process into a new registry of paperwork. It is a compact editorial discipline for anyone reporting a major language change. It lets a reader reconstruct the relevant handoff without converting a room of discussion into a general mandate or a decision into a promise that every downstream environment can safely consume it.

Sources

  1. PEP 1 — PEP Purpose and Guidelines
  2. PEP 13 — Python Language Governance
  3. Python Developer’s Guide — Development cycle
  4. Lu Heng, The Multi-Stakeholder Mirage
  5. Lu Heng, Running-Code Primacy