Jelle Zijlstra

Notes on the CPython project

These are some personal notes on how to work with the CPython project. They focus on triaging and merging pull requests.

Roles

CPython uses labels for many purposes. Only triagers and core developers can apply labels. Some are only supposed to be added or removed by bots (e.g., “awaiting review”, added by Bedevere). Others are added or removed by humans and bots (e.g., “docs” or “tests”).

Triagers can also do the following:

Core developers can:

Buildbots

Every PR runs CPython’s regular CI, which includes running the full test suite on a few operating systems, building the docs, and running make patchcheck.

Optionally, PRs can be tested on the buildbot fleet by adding the “test with buildbots” label. The buildbots run on a wide variety of configurations and systems. In my experience, the following are the most important unique aspects:

I tend to run the buildbots for every nontrivial change that affects C code. For changes that only affect Python code or the docs, the buildbots don’t add much value. It may also be useful to run the buildbots for changes in Python modules that interact directly with the OS, such as ssl or asyncio, but I don’t usually work on such modules.

Backporting

In CPython, virtually all pull requests are first made against main, the feature branch, which represents the next 3.x version to be released. After a PR is merged into main, if there is a “needs backport to 3.x” label on the PR, the Miss Islington bot will automatically try to create a backport PR applying the change to the 3.x branch.

Sometimes the bot can’t create a PR because there is a conflict. In that case, you have to use the cherry_picker tool on the command line to fix the conflict and create the backport PR manually. Occasionally the bot posts a message saying something like “could not checkout the 3.x branch”. In that case, simply remove the label for that branch and reapply it, and the bot will try again, usually successfully.

GitHub automerge is especially useful for backport PRs: if automerge is enabled on a PR, the PR will be automatically merged after all “required” CI checks have passed. (It isn’t required for the PR to have been approved for automerge to succeed.) I will usually look over the PR to make sure it makes sense, enable automerge, and assign it to myself. I check the list of PRs assigned to me regularly, so if CI doesn’t pass or something, I’ll come back to the PR later to get it merged. My workflow is to check back a few hours later and merge if CI has passed by then.

What to backport?

But the most difficult question is: When do we backport? The short answer is that bugfixes get backported and new features don’t, but what is a bug and what is a feature?

Here are some rules I’ve come up with:

“skip issue” and “skip news”

Significant changes to CPython require an issue to be created, and most also require a news entry. You can use the blurb command-line tool or the blurb-it website to create a news entry.

When to skip news

News entries are used to create a changelog with all user-relevant changes since the previous release. Therefore, every change that could potentially affect users should have a news entry. Some categories of changes that don’t need news include:

There is little harm in adding a news entry if it is not strictly required, so if I’m in doubt and the PR author has already created a news entry, I’ll usually let it stand.

When to skip issue

News entries are keyed on the issue number, so every change that requires a news entry also requires an issue. The converse isn’t always true: sometimes a change fixes an issue, but doesn’t need a news entry. For example, wording changes in the documentation are often discussed in an issue first, but usually don’t require a news entry. Similarly, fixes to unreleased features may be discussed in an issue, but don’t usually need a news entry.

Merging a PR

There is no requirement that core developers get approval from anyone else before merging a PR, but I feel that we should strongly avoid merging unreviewed code. For my own PRs, ideally I would want review from another core dev, or failing that from someone else who I trust enough to know that they will review the PR with a critical eye.

When reviewing a PR from a non-core dev, I’ll approve the PR when I feel it’s ready to merge, then wait a while to give others a chance to chime in and tell me I’m wrong. This is especially important for older PRs where another core dev has previously provided feedback. If they requested changes, it’s best to get explicit signoff from them before merging.

Closing a PR

Sometimes a PR clearly isn’t going to be merged. In that case, it should be closed. Example scenarios:

It’s not a good experience for users when their PR gets closed, so I try to be diplomatic.