PyPA Lightweight Governance Model
In order to better serve the Python Packaging ecosystem, the following governance model is proposed for the Python Packaging Authority.
The following defines the various roles that may interact within the PyPA.
Anyone with the commit bit on at least one project in the PyPA organization, which should correspond to everyone on the PyPA-Committers mailing list.
Essentially anyone who is interested in PyPA activity and wants to follow along or make proposals.
As described in https://wiki.python.org/psf/PackagingWG
Interest Area Authority
A single person, nominated by the PyPA, who acts as the decision maker for a specific Interest Area within the PyPA. This person has the authority to accept or reject proposals within their corresponding Interest Area, and will continue to do so until they step down, or are replaced by a vote of the PyPA members.
Below are the primary goals and non-goals for the PyPA and it's governance model.
Goals of the PyPA
These goals are the primary motivation for the existence of the PyPA. These goals are largely already being carried out, even though most have not been explicitly defined.
Provide support for existing projects under the PyPA
In the event that a given project needs additional support, or no longer has active maintainers, the PyPA will ensure that the given project will continue to be supported for users to the extent by which is necessary
Foster the creation and acceptance of standards for PyPA projects
The PyPA should, as much as possible, strive for standardization and coordination across PyPA projects, primarily though the governance process outlined below.
Guide decisions which affect multiple PyPA projects
The PyPA community (especially PyPA members) should be expected to provide opinions, insight and experience when ecosystem-wide changes are being proposed.
Determine which projects should be under the guidance of the PyPA
For example: accepting new projects from the community, creating projects organically by the PyPA, etc. This is done via the same governance process.
Enforce adherence to the CoC uniformly across all projects
Generally this means leading by example, but occasionally it may mean more explicit moderation.
Non-goals of the PyPA
These are specific items that are explicitly not goals of the PyPA.
Determine who is and isn't a PyPA member
This is for maintainers of individual projects to decide as they add new maintainers (committers) to their projects. Maintainership of a project that is under the PyPA organization automatically transfers membership in the PyPA.
Micromanage individual projects development
As long as the project is adhering to the Code of Conduct, the PyPA should only concerned with large, ecosystem-wide changes.
Goals of the PyPA's Governance Model
These are new goals which the governance model seeks to make possible.
Provide a consensus-driven decision-making process
This will provide a more structured method of proposing and introducing changes than what currently exists, as well as a means by which PyPA members can decide which proposals will be accepted or rejected.
Provide a transparent record of proposed, accepted and rejected decisions
Via an RFC process (described below), the proposed changes to the PyPA ecosystem will be centralized and standardized. This will allow both PyPA members and the wider PyPA community to understand the rationale, process and resolution of any change to the ecosystem.
The process for PyPA governance is outlined below:
Lightweight Decision-Making Process:
1. Creation of a Request for Comments (RFC)
The RFC is created to propose changes to the PyPA ecosystem, with initial proposal, alternatives and trade-offs, and submitted as a pull request to the
pypa/rfcs repository. The structure of the RFC is defined below.
2. Comments period
During this period, the PyPA community and PyPA members publicly discuss the RFC to raise issues or concerns with the proposal, as comments on the pull request.
3. Revision of the RFC by the author(s) to address comments
This should be repeated above until "major objections" are fully addressed, or it's clear that there is a fundamental choice to be made.
If the RFC falls under a specific Interest Area, then the corresponding Interest Area Authority will review the proposal and decide whether it should be accepted or rejected.
If the RFC does not fall under a specific Interest Area, the proposal will be put to a vote by the PyPA members (via the PyPA-committers mailing list) to confirm consensus (at least two +1's, more +1's than +0's, and no -1's) over a 5 day period.
The voting period should not include any significant changes to the RFC -- this should happen in the previous step, where anyone can participate. Voting should also not be conditional, e.g. "+1 if we make it do X instead of Y".
If the RFC falls under a specific Interest Area, but the Interest Area Authority has recused themselves, has not made a decision within 30 days, or is otherwise unavailable, then the RFC is put to a vote as above.
Once the review period has concluded, the pull request is then amended to reflect the resulting status, merged, and the result is shared with the PyPA-committers mailing list.
6. Implementation of the proposed change by maintainers
If accepted, various maintainers then make the necessary changes.
7. Conversion of the RFC into an Architectural Decision Record (ADR)
Once implemented, the document should be updated in order to record what was actually implemented (if it differed from the proposed implementation).
What requires an RFC:
The following are examples of situations where an RFC should be proposed.
Significant user-facing changes
Any change which is apparent to the user (highly visible new features, etc). This should not be for trivial changes, and thus should be used at the project maintainer's discretion (or upon suggestion from the PyPA).
Significant breaking changes or deprecations
Any change which removes existing functionality or introduces a breaking change (e.g., deprecating the
python setup.py register command). This should not be for trivial changes, and thus should be used at the project maintainer's discretion (or upon suggestion from the PyPA).
Changes affecting multiple PyPA projects
Any change which would require modifications to more than one PyPA project (e.g., implementation of
Description-Content-Type for Markdown READMEs)
New tools, systems, or standards
Either proposing the creation of a new tool, system, or standard, or to accept a new project into the PyPA organization.
Changes to PyPA Governance or Policy
Anything which would change how the PyPA or it's governance process works. Policy proposals should not be mixed with non-policy proposals (e.g., a proposal like PEP 541 "Package Index Name Retention" would not be mixed with a proposal detailing how PyPI plans to implement said policy).
Creating a RFC:
Below are the key components of an RFC:
The filename should be sequential, containing the RFC number followed by the title. Example:
The title should be brief and to the point, short enough to fit in a commit message. Example:
# Title RFC-001: Adopting Python 3
The corresponding Interest Area for this proposal. This will determine which Interest Area Authority, if any, will review.
The summary should be short and concise, maybe even 140 characters or less.
# Summary We decided to upgrade from Python 2 to Python 3 to support Unicode better.
The context describes the state of the system when the decision was made. It also records other external forces that come into play.
This should eventually become out of date, but still be contextually relevant. Without this context, the decision record might not make sense when reviewed in hindsight. And usually the implementation of this particular architectural decision will make the context out of date—but this is fine. For example:
# Context We are currently using Python 2 everywhere. The users want to start sending us Unicode characters in the API.
The decision is made up of full sentences, in the active voice. Example:
# Decision We will migrate to Python 3 for services X, Y and Z.
This section should list all consequences (not just the benefits) to the decision, including what could go wrong. Example:
# Consequences We will be able to handle Unicode characters, but we might have to provide backwards-compatible support for some dependencies that haven't been ported to Python 3 yet.
The status section should only be one of the six following statuses. The flow is diagrammed as follows:
Proposed -----> Accepted ----> Implemented | | | V V V Rejected Deprecated ----> Superseded
A status of "Proposed" is the initial status of a newly created RFC, during the proposal, comment and consensus period.
A status of "Accepted" is assigned after a vote on the RFC has achieved consensus.
A status of "Rejected" is assigned after a vote on the RFC has failed to achieve consensus.
A status of "Implemented" is assigned after the proposed change has been completed by all necessary maintainers.
At the point at which the status changes from "Accepted" to "Implemented", the RFC should be revised to become an Architectural Decision Record (ADR), to accurately describe the true state of the ecosystem after implementation.
A status of "Deprecated" is assigned to an RFC that was accepted, but either was not or could not be implemented.
A status of "Superseded" is assigned when a new RFC is proposed which obviates a previously implemented ADR. A link should be provided to the decision record which supersedes it:
# Status Superseded by [ADR-002](/adrs/002-going-back-to-python-2.md)
This section should contain relevant links depending on the status of the proposal. Example:
# Links Discussion: <https://github.com/pypa/rfcs/pull/42 Vote: <https://email@example.com/thread/.../>
Does this mean that we won't be using the PEP process anymore?
For a number of things we currently use the PEP process for, such as defining standards, making changes to package metadata fields, etc., the answer is yes, this governance model is designed to replace that process, with these advantages:
- Lower barrier to entry for proposal authors
- Wider audience of reviewers
- More accessible to the community
This doesn't mean that we can't use the PEP process anymore, however, it just limits the scope to changes that require it. This is somewhat subjective, but generally if a proposed change requires modifying CPython itself, it should be a PEP.