CPython uses a workflow based on pull requests. What this means isthat you create a branch in Git, make your changes, push those changesto your fork on GitHub (origin
), and then create a pull request againstthe official CPython repository (upstream
).
Clear communication is key to contributing to any project, especially anOpen Source project like CPython.
Here is a quick overview of how you can contribute to CPython:
Create an issue that describes your change[*]
Create a new branch in Git from themain
branch
Work on changes: fix a bug or add a new feature
Run tests andmakepatchcheck
Create Pull Request on GitHub to merge a branch from your fork
Make sure thecontinuous integration checks on your Pull Requestare green (successful)
Review and addresscomments on your Pull Request
When your changes are merged, you candelete the PR branch
Celebrate contributing to CPython! :)
If an issue is trivial (for example, typo fixes), or if an issue already exists,you can skip this step.
Note
In order to keep the commit history intact, please avoid squashing or amendinghistory and then force-pushing to the PR. Reviewers often want to look atindividual commits.
You should have alreadyset up your system,got the source code, andbuilt Python.
Update data from yourupstream
repository:
gitfetchupstream
Create a new branch in your local clone from themain
branchin the upstream repository:
gitcheckout-b<branch-name>upstream/main
Note
Almost all changes to Python, including bug fixes, should first bemade against themain
branch. Seehere formore details.
Make changes to the code, and usegitstatus
andgitdiff
to see them.
(Learn more aboutMaking good PRs)
Make sure the changes are fine and don’t cause any test failure:
makepatchcheck./python-mtest
(Learn more aboutpatchcheck and aboutRunning and writing tests)
Once you are satisfied with the changes, add the files and commit them:
gitadd<filenames>gitcommit-m'<message>'
(Learn more aboutMaking good commits)
If your code isn’t linted correctly,pre-commitwill block the commit with an error message, for example:
Doc/library/stdtypes.rst:5718:Nonewlineatendoffile.(missing-final-newline)
Once all linting errors have been fixed, you can push your work to your GitHub fork:
gitpushorigin<branch-name>
Finally go onhttps://github.com/<your-username>/cpython
: you willsee a box with the branch you just pushed and a green button that allowsyou to create a pull request against the official CPython repository.
When people start adding review comments, you can address them by switchingto your branch, making more changes, committing them, and pushing them toautomatically update your PR:
gitswitch<branch-name># make changes and run testsgitadd<filenames>gitcommit-m'<message>'gitpushorigin<branch-name>
If a core developer reviewing your PR pushed one or more commits to yourPR branch, then after checking out your branch and before editing, run:
gitpullorigin<branch-name># pull = fetch + merge
If you have made local changes that have not been pushed to your fork andthere are merge conflicts, Git will warn you about this and enter conflictresolution mode. SeeResolving merge conflicts below.
If time passes and there are merge conflicts with the main branch, GitHubwill show a warning to this end and you may be asked to address this. Mergethe changes from the main branch while resolving the conflicts locally:
gitswitch<branch-name>gitpullupstreammain# pull = fetch + merge# resolve conflicts: see "Resolving Merge Conflicts" belowgitpushorigin<branch-name>
After your PR has been accepted and merged, you candelete the branch:
gitbranch-D<branch-name># delete local branchgitpushorigin-d<branch-name># delete remote branch
When merging changes from different branches (or variants of a branch ondifferent repos), the two branches may contain incompatible changes to oneor more files. These are called “merge conflicts” and need to be manuallyresolved as follows:
Check which files have merge conflicts:
gitstatus
Edit the affected files and bring them to their intended final state.Make sure to remove the special “conflict markers” inserted by Git.
Commit the affected files:
gitadd<filenames>gitmerge--continue
When running the final command, Git may open an editor for writing a commitmessage. It is usually okay to leave that as-is and close the editor.
Seethe merge command’s documentationfor a detailed technical explanation.
When creating a pull request for submission, there are several things that youshould do to help ensure that your pull request is accepted.
Make your change against the right version of Python. In general allchanges are made against themain
branch first. This includes bug fixes.After the change is merged there, it will beported backto oldermaintenance releases as well. That way weensure all affected versions are handled. Therefore, basing a new changedirectly on a maintenance branch is only used in specific circumstances,for instance when that change does not apply tomain
or the changerequires a different approach in an older Python version compared tomain
.
Make sure to follow Python’s style guidelines. For Python code youshould followPEP 8, and for C code you should followPEP 7. If you haveone or two discrepancies those can be fixed by the core developer who mergesyour pull request. But if you have systematic deviations from the style guidesyour pull request will be put on hold until you fix the formatting issues.
Note
Pull requests with only code formatting changes are usually rejected. Onthe other hand, fixes for typos and grammar errors in documents anddocstrings are welcome.
Be aware of backwards-compatibility considerations. While the coredeveloper who eventually handles your pull request will make the final call onwhether something is acceptable, thinking about backwards-compatibility earlywill help prevent having your pull request rejected on these grounds. Putyourself in the shoes of someone whose code will be broken by the change(s)introduced by the pull request. It is quite likely that any change made willbreak someone’s code, so you need to have a good reason to make a change asyou will be forcing someone to update their code. (This obviously does notapply to new classes or functions; new arguments should be optional and havedefault values which maintain the existing behavior.) If in doubt, have a lookatPEP 387 ordiscuss the issue with experienceddevelopers.
Make sure you have proper tests to verify your pull request works asexpected. Pull requests will not be accepted without the proper tests!
Make sure all tests pass. The entire test suite needs torunwithout failure because of your changes.It is not sufficient to only run whichever test seems impacted by yourchanges, because there might be interferences unknown to you between yourchanges and some other part of the interpreter.
Properdocumentation additions/changes should be included.
Copyright notices are optional and informational, as international treatieshave abolished the requirement for them to protect copyrights.However, they still serve an informative role.
According to the US Copyright Office, valid copyright notices include the yearof first publication of the work. For example:
Copyright (C) 2001 Python Software Foundation.
Updating notices to add subsequent years is unnecessary and such PRs will beclosed.
See alsopython/cpython#126133.
patchcheck
¶patchcheck
is a simple automated checklist for changes in progress thatguides a developer through common checks. To runpatchcheck
:
OnUnix (including macOS):
makepatchcheck
OnWindows (after any successful build):
.\python.bat Tools\patchcheck\patchcheck.py
The automated checklist runs through:
Are there any whitespace problems in Python files?(usingTools/patchcheck/reindent.py)
Are there any whitespace problems in C files?
Are there any whitespace problems in the documentation?
Has the documentation been updated?
Has the test suite been updated?
Has an entry underMisc/NEWS.d/next
been added?(usingblurb-it,or theblurb tool)
HasMisc/ACKS
been updated?
Hasconfigure
been regenerated, if necessary?
Haspyconfig.h.in
been regenerated, if necessary?
The automated checks don’t actuallyanswer all of thesequestions. Aside from the whitespace checks, the tool isa memory aid for the various elements that can go intomaking a complete pull request.
Each feature or bugfix should be addressed by a single pull request,and for each pull request there may be several commits. In particular:
Donot fix more than one issue in the same commit (except,of course, if one code change fixes all of them).
Donot do cosmetic changes to unrelated code in the samecommit as some feature/bugfix.
Commit messages should follow the following structure:
MakethespammodulemorespammyThespammodulesporadicallycameupshortonspam.Thischangeraisestheamountofspaminthemodulebymakingitmorespammy.
The first line or sentence is meant to be a dense, to-the-point explanationof what the purpose of the commit is. The imperative form (used in the exampleabove) is strongly preferred to a descriptive form such as ‘the spam module isnow more spammy’. Usegitlog--oneline
to see existing title lines.Furthermore, the first line should not end in a period.
If this is not enough detail for a commit, a new paragraph(s) can be addedto explain in proper depth what has happened (detail should be good enoughthat a core developer reading the commit message understands thejustification for the change).
Checkthe Git bootcamp for furtherinstructions on how the commit message should look like when merging a pullrequest.
Note
How to Write a Git Commit Messageis a nice article that describes how to write a good commit message.
To accept your change we must have your formal approval for distributingyour work under thePSF license. Therefore, you need to sign acontributor agreement which allows thePython Software Foundation tolicense your code for use with Python (you retain the copyright).
Note
You only have to sign this document once, it will then apply to allyour further contributions to Python.
Here are the steps needed in order to sign the CLA:
Create a change and submit it as a pull request.
Whenpython-cla-bot
comments on your pull request that commitauthors are required to sign a Contributor License Agreement, clickon the button in the comment to sign it. It’s enough to log in throughGitHub. The process is automatic.
After signing, the comment bypython-cla-bot
will update toindicate that “all commit authors signed the Contributor LicenseAgreement”.
Once you are satisfied with your work you will want to commit yourchanges to your branch. In general you can rungitcommit-a
andthat will commit everything. You can always rungitstatus
to seewhat changes are outstanding.
When all of your changes are committed (that is,gitstatus
doesn’tlist anything), you will want to push your branch to your fork:
gitpushorigin<branchname>
This will get your changes up to GitHub.
Now you want tocreate a pull request from your fork.If this is a pull request in response to a pre-existing issue on theissue tracker, please make sure to reference the issue number usinggh-NNNNN:
prefix in the pull request title and#NNNNN
in the description.
If this is a pull request for an unreported issue (assuming you alreadyperformed a search on the issue tracker for a pre-existing issue), create anew issue and reference it in the pull request. Please fill in as muchrelevant detail as possible to prevent reviewers from having to delayreviewing your pull request because of lack of information.
If this issue is so simple that there’s no need for an issue to trackany discussion of what the pull request is trying to solve (for example, fixing aspelling mistake), then the pull request needs to have the “skip issue” labeladded to it by someone with commit access.
Your pull request may involve several commits as a result of addressing codereview comments. Please keep the commit history in the pull request intact bynot squashing, amending, or anything that would require a force push to GitHub.A detailed commit history allows reviewers to view the diff of one commit toanother so they can easily verify whether their comments have been addressed.The commits will be squashed when the pull request is merged.
When a patch exists in theissue tracker that should be converted into aGitHub pull request, please first ask the original patch author to preparetheir own pull request. If the author does not respond after a week, it isacceptable for another contributor to prepare the pull request based on theexisting patch. In this case, both parties should sign theCLA.When creating a pull request based on another person’s patch, provideattribution to the original patch author by adding “Co-authored-by:Author Name <email_address> .” to the pull request description and commit message.Seethe GitHub articleon how to properly add the co-author info.
See alsoApplying a Patch to Git.
To begin with, please be patient! There are many more peoplesubmitting pull requests than there are people capable of reviewingyour pull request. Getting your pull request reviewed requires areviewer to have the spare time and motivation to look at your pullrequest (we cannot force anyone to review pull requests and no one isemployed to look at pull requests). If your pull request has notreceived any notice from reviewers (that is, no comment made) after onemonth, first “ping” the issue on theissue tracker to remind thesubscribers that the pull request needs a review.If you don’t get a response within a week after pinging the issue,you can post on theCore Development Discourse categoryto ask for someone to review your pull request.
When someone does manage to find the time to look at your pull requestthey will most likely make comments about how it can be improved(don’t worry, even core developers of Python have their pull requests sentback to them for changes). It is then expected that you update yourpull request to address these comments, and the review process willthus iterate until a satisfactory solution has emerged.
One of the bottlenecks in the Python developmentprocess is the lack of code reviews.If you browse the bug tracker, you will see that numerous issueshave a fix, but cannot be merged into the main source code repository,because no one has reviewed the proposed solution.Reviewing a pull request can be just as informative as providing apull request and it will allow you to give constructive comments onanother developer’s work. This guide provides a checklist forsubmitting a code review. It is a common misconception that in orderto be useful, a code review has to be perfect. This is not the case atall! It is helpful to just test the pull request and/or play around with thecode and leave comments in the pull request or issue tracker.
If you have not already done so, get a copy of the CPython repositoryby following thesetup guide, build it and run the tests.
Check the bug tracker to see what steps are necessary to reproducethe issue and confirm that you can reproduce the issue in your versionof the Python REPL (the interactive shell prompt), which you can launchby executing ./python inside the repository.
Checkout and apply the pull request (Please refer to the instructionChecking out others’ pull requests)
If the changes affect any C file, run the build again.
Launch the Python REPL (the interactive shell prompt) and check ifyou can reproduce the issue. Now that the pull request has been applied,the issue should be fixed (in theory, but mistakes do happen! A good reviewaims to catch these before the code is merged into the Python repository).You should also try to see if there are any corner cases in this or relatedissues that the author of the fix may have missed.
If you have time, run the entire test suite. If you are pressed for time,run the tests for the module(s) where changes were applied.However, please be aware that if you are recommending a pull request as‘merge-ready’, you should always make sure the entire test suite passes.
When you review a pull request, you should provide additional details and contextof your review process.
Instead of simply “approving” the pull request, leave comments. For example:
If you tested the PR, report the result and the system and version tested on,such as ‘Windows 10’, ‘Ubuntu 16.4’, or ‘Mac High Sierra’.
If you request changes, try to suggest how.
Comment on what is “good” about the pull request, not just the “bad”. Doingso will make it easier for the PR author to find the good in your comments.
Look at any failures in CI on the current PR. See“Keeping CI green” below for simple things you can do to help move the PR forward.
A core developer can dismiss another core developer’s review if they confirmedthat the requested changes have been made. When a core developer has assignedthe PR to themselves, then it is a sign that they are actively looking afterthe PR, and their review should not be dismissed.
Our change management workflows generally won’t allow merging PRs withfailures. Therefore, if you see a CI failure on a PR, have a lookwhat it is about.
Usually the failure will be directly related to the changes in the currentPR. If you happen to have any insight into the failure, let the author knowin a review comment. CI runs sometimes generate thousands of lines of output.Even something as simple as finding the traceback and putting it in thecomment will be helpful to the PR author.
If the failure doesn’t look related to the change you’re looking at, checkif it’s not present on theRelease Status Buildbot dashboard as well.If so, that means the failure was introduced in a prior change. Using Buildbot’sUI you can find which PR introduced the issue and comment that itaffects other PRs.
If you still don’t see where the failure originates from, check fora “This branch is out-of-date with the base branch” sign next to thelist of executed checks. Clicking “Update branch” next to this messagewill merge in the latest changes from the base branch into the PR.
If this still doesn’t help with the failure on the PR, you can tryto re-run that particular failed check. Go to the red GitHub Action job,click on theRe-run jobs button on the top right, and selectRe-run failed jobs. The button will only be present when all otherjobs finished running.
Re-running failed jobs shouldn’t be your first instinct but it is occasionallyhelpful because distributed systems can have intermittent failures, andsome of our unit tests are sensitive to overloaded virtual machines.If you identify such flaky behavior, look for an issue in theissue trackerthat describes this particular flakiness. Create a new issue if you can’tfind one.
You can click on theUpdate branch button to merge the latestchanges from the base branch (usuallymain
) into the PR.This is useful tokeep the CI green for old PRs,or to check if a CI failure has been fixed in the base branch.
If the PR is very old, it may be useful to update the branch before merging toensure that the PR does not fail any CI checks that were added or changed sinceCI last ran.
Do not clickUpdate branch without a good reason because it notifieseveryone watching the PR that there are new changes, when there are not,and it uses up limited CI resources.
Once your pull request has reached an acceptable state (and thus considered“accepted”), it will either be merged or rejected. If it is rejected, pleasedo not take it personally! Your work is still appreciated regardless of whetheryour pull request is merged. Balancing whatdoes anddoes not go intoPython is tricky and we simply cannot accept everyone’s contributions.
But if your pull request is merged it will then go into Python’sVCS to be releasedwith the next feature release of Python. It may also be backported to olderversions of Python as a bugfix if the core developer doing the merge believesit is warranted.
Non-trivial contributions are credited in theMisc/ACKS
file (and, mostoften, in a contribution’s news entry as well). You may beasked to make these edits on the behalf of the core developer whoaccepts your pull request.