-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
PEP 779: Criteria for supported status for free-threaded Python initial draft #4301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
81bb9dc
Initial draft of PEP 703 phase II promotion requirements.
Yhg1s 9c56720
Markup fixes.
Yhg1s aae7310
Markup fixes.
Yhg1s 74d1b87
Markup fixes.
Yhg1s 2fcba50
More markup fixes, because why not.
Yhg1s 62eb654
Fix a few more lint issues.
Yhg1s bce15aa
Spelling fixes courtesy of mpage.
Yhg1s 94c8902
Update based on feedback.
Yhg1s 8c3b8fe
Slight elaboration.
Yhg1s 76495c1
Add co-authors.
Yhg1s 0d8e1af
Reformat a little.
Yhg1s a9f1379
Minor language changes.
Yhg1s 4b2d899
Rename to lowest available number.
Yhg1s 4760487
Use Matt's shiny new email address.
Yhg1s File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,174 @@ | ||||||
PEP: 779 | ||||||
Title: Criteria for supported status for free-threaded Python | ||||||
Author: Thomas Wouters <[email protected]>, | ||||||
Matt Page <mpage at python.org>, | ||||||
Sam Gross <colesbury at gmail.com> | ||||||
Status: Draft | ||||||
Type: Standards Track | ||||||
Created: 03-Feb-2025 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the date the PEP number was assigned:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in #4302 |
||||||
Python-Version: 3.14 | ||||||
|
||||||
|
||||||
Abstract | ||||||
======== | ||||||
|
||||||
The acceptance of :pep:`703` (Making the Global Interpreter Lock Optional in | ||||||
CPython), as `announced by the Steering Council | ||||||
<https://discuss.python.org/t/pep-703-making-the-global-interpreter-lock-optional-in-cpython-acceptance/37075>`__, | ||||||
describes three phases of development for the work to remove the Global | ||||||
Interpreter Lock. Phase I started early in the development of Python 3.13, | ||||||
and includes making the free-threaded (GIL-less) Python build available but | ||||||
explicitly *experimental*. Phase II would make the free-threaded build | ||||||
officially supported but still optional, and phase III would make the | ||||||
free-threaded build the default. Because of the number of unknowns at the | ||||||
time, the criteria for moving to the next phase were left deliberately vague | ||||||
at the time. This PEP establishes clear expectations and requirements for | ||||||
moving to Phase II, making the free-threaded Python build officially | ||||||
supported. | ||||||
|
||||||
.. note:: | ||||||
|
||||||
Eagle-eyed readers may have noticed an overlap in authors of this PEP and | ||||||
the Steering Council at the time of PEP 703 acceptance. The SC makeup has | ||||||
since changed, but just to make it explicit: this PEP as proposed, while | ||||||
based on criteria set forth by the SC, does not come from the Steering | ||||||
Council itself. | ||||||
|
||||||
Motivation | ||||||
========== | ||||||
|
||||||
Whether to move forward with :pep:`703` (as well as ultimately making it the | ||||||
default) is a question of whether the costs outweigh the benefits. Making | ||||||
free-threaded Python an officially supported build is important to signal | ||||||
that we're now at a stage where the design is finalised, the APIs are usable | ||||||
and stable, and we're satisfied the performance and complexity cost is not | ||||||
prohibitive. | ||||||
|
||||||
Moving to the "officially supported" stage is an important step towards | ||||||
making free-threaded Python the default build, and eventually the only one. | ||||||
Before we can decide we're ready to make it the default, we need a much | ||||||
better picture of the costs and the benefits, and we can only get there if | ||||||
more of the Python ecosystem starts supporting free-threaded Python. We | ||||||
currently have enough packages and tools supporting :pep:`703` that it's | ||||||
clear we're on the right path, but not enough to make the final decision. In | ||||||
addition to giving the Python community time to make the changes necessary | ||||||
to support free-threaded Python, we expect to use phase II to show clear | ||||||
benefits in real-world applications, as well as clearly define the cost in | ||||||
terms of performance, support burden, and ecosystem complexity. | ||||||
|
||||||
Rationale | ||||||
========= | ||||||
|
||||||
In order for PEP 703 to be acceptable it should be desirable, stable, | ||||||
maintainable, performant (in CPU and memory), and ideally it should have | ||||||
Stable ABI so the same wheels can be used for free-threaded and with-GIL | ||||||
builds. | ||||||
|
||||||
- Desirability: from various experiments it's very clear free-threaded | ||||||
Python has tremendous potential benefit. It's not a simple drop-in | ||||||
solution -- some code will have to be redesigned to make the most of the | ||||||
new capability, as well as avoid performance pitfalls -- but it can | ||||||
achieve higher performance, significantly lower latency and new | ||||||
thread-based functionality when embraced. | ||||||
|
||||||
- Stability: the majority of the new API design is in 3.13, and is being | ||||||
successfully used to support free-threaded Python in a number of | ||||||
third-party packages (see for example | ||||||
https://py-free-threading.github.io/tracking/). There's been some more | ||||||
development in 3.14 to add more convenience functions, and to replace | ||||||
APIs that previously relied on the GIL for thread-safety, but we have not | ||||||
had to break the 3.13 APIs for free-threaded Python. | ||||||
|
||||||
- Maintainability: the majority of :pep:`703`'s design is relatively | ||||||
simple, with most complexity hidden away behind CPython's existing C | ||||||
APIs. The implementation details of, for example, lockless list and dict | ||||||
APIs, `which rely on QSBR <https://github.com/python/cpython/issues/115103>`_, | ||||||
and `deadlock-avoiding critical sections <https://github.com/python/cpython/issues/115103>`_, | ||||||
may be complex and difficult to get right, but gives us easy to use APIs | ||||||
without too many pitfalls. Making more of CPython free-threading-safe is | ||||||
a relatively simple process, although we do probably need more | ||||||
documentation on the basic guarantees the new APIs provide | ||||||
(https://github.com/python/cpython/issues/128642). | ||||||
|
||||||
- Performance: the performance penalty on linear performance, comparing a | ||||||
free-threaded build against a with-GIL build, as measured by the | ||||||
pyperformance benchmarks (for example as run by `Microsoft's Faster | ||||||
CPython team <https://github.com/faster-cpython/benchmarking-public/>`_, | ||||||
or `Meta's Python Runtime team <https://github.com/facebookexperimental/free-threading-benchmarking>`_), | ||||||
is currently around 10% (except on macOS, where it's more like 3%). We | ||||||
have a few more PRs in flight that should get us comfortably below 10% on | ||||||
Linux and Windows. | ||||||
|
||||||
- Memory use. Exact numbers vary because of the different gc module | ||||||
implementation, but free-threaded Python currently sees about 15-20% | ||||||
higher memory use (geometric mean, as measured by pyperformance). We | ||||||
haven't spent a lot of time trying to lower this yet, so we may be able to | ||||||
push this down further. Realistically, though, higher memory use is the | ||||||
cost of having efficient, safe free-threading, and we are unlikely to get | ||||||
this very close to the with-GIL build's memory use without significant | ||||||
performance cost. | ||||||
|
||||||
- Stable ABI. Stable ABI support is mentioned by the Steering Council as a | ||||||
potential requirement for phase II. While having Stable ABI support would | ||||||
make third-party package distribution a lot easier, there's a bit of a | ||||||
chicken and egg problem: we don't know if the Stable ABI is good enough | ||||||
if we don't have packages that support free-threaded Python using it, and | ||||||
we can't remove things from the Stable ABI if we discover problems with | ||||||
them. Given that phase II is meant to give the community time to adopt | ||||||
free-threaded Python and provide feedback on APIs and ABIs, we're not | ||||||
sure how strong a requirement the Stable ABI should be for phase II. | ||||||
|
||||||
Specification | ||||||
============= | ||||||
|
||||||
Specific criteria for making free-threaded Python officially supported | ||||||
(phase II), as we propose them: | ||||||
|
||||||
- Acceptable performance. The Steering Council mentioned they expected | ||||||
free-threaded Python to be around 10-15% slower, although this was not a | ||||||
hard target. We are currently around 10% and don't expect it to get | ||||||
slower, but for phase II (not the default flip), we propose 15% as a hard performance target. | ||||||
|
||||||
- Acceptable memory use. This was not mentioned by the Steering Council and | ||||||
hasn't seen much discussion. We propose a target of 20% (geometric mean, | ||||||
as measured by pyperformance) for phase II. For phase III, we'll need | ||||||
input from the community as to where the trade-off between memory and CPU | ||||||
performance should end up. | ||||||
|
||||||
- Proven, stable APIs. This is a difficult thing to measure, but we have | ||||||
seen significant adoption of free-threaded Python with the existing APIs, | ||||||
and have not had to radically change any existing APIs to accommodate | ||||||
them. We will probably end up adding some more convenience APIs for | ||||||
specific use-cases in the future, but we believe we have proven the | ||||||
viability and stability of the APIs we have. We have not needed | ||||||
breaking changes in new APIs, and we expect all future changes | ||||||
to follow :pep:`387`'s change policy. | ||||||
|
||||||
- Internal documentation. We have multiple Core Developers working on | ||||||
free-threaded Python, including several who recently started working on | ||||||
fixing thread-safety issues in specific modules, but we probably need to | ||||||
shore up the introductory documentation for the internals of | ||||||
free-threaded Python. This should not be a problem to achieve for 3.14. | ||||||
|
||||||
With these criteria satisfied, we believe Python 3.14 is the right time frame | ||||||
for phase II of :pep:`703`. | ||||||
|
||||||
(Note that these are requirements for entering phase II *only*. The decision | ||||||
to make free-threaded Python the default (phase III) is very different, and | ||||||
we expect it will revolve around community support, willingness, and showing | ||||||
clear benefit. That's left for a future PEP.) | ||||||
|
||||||
Open Issues | ||||||
=========== | ||||||
|
||||||
- Should the Stable ABI be a strong requirement for "supported" status of the free-threaded build? | ||||||
|
||||||
|
||||||
Footnotes | ||||||
========= | ||||||
|
||||||
Copyright | ||||||
========= | ||||||
|
||||||
This document is placed in the public domain or under the | ||||||
CC0-1.0-Universal license, whichever is more permissive. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason not to use 776, the next in sequence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw 777 being used and 778 in the PRs, so I assumed 779 was the next one. Do you want me to renumber it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine, you've already opened the discussion, we can fill the gap later.
777 was used out of sequence (re: #3786 (comment)).
Tip: this checks both published PEPs and pending PRs: