Skip to content

Commit 2c2e424

Browse files
committed
Merge remote-tracking branch 'upstream/main' into rm-x
2 parents 50cdc3f + e479320 commit 2c2e424

11 files changed

Lines changed: 306 additions & 61 deletions

File tree

.github/dependabot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
version: 2
22
updates:
3-
- package-ecosystem: npm
3+
- package-ecosystem: bun
44
directory: /
55
schedule:
66
interval: monthly

bun.lock

Lines changed: 65 additions & 55 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

content/authors/emma-smith.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "Emma Smith",
3+
"bio": "CPython Core Developer and Rust for CPython co-lead",
4+
"github": "emmatyping",
5+
"avatar": "",
6+
"twitter": "",
7+
"bluesky": "emmatyping.dev",
8+
"mastodon": "https://hachyderm.io/@emmatyping",
9+
"website": "https://emmatyping.dev",
10+
"featured": false
11+
}

content/authors/ken-jin.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "Ken Jin",
3+
"bio": "Ken Jin is a Python core team member since Aug 2021. He works primarily on Python's performance.",
4+
"github": "Fidget-Spinner",
5+
"avatar": "",
6+
"twitter": "",
7+
"bluesky": "",
8+
"mastodon": "",
9+
"website": "https://fidget-spinner.github.io",
10+
"featured": false
11+
}
287 KB
Loading
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
title: Python 3.15's JIT is now back on track
3+
publishDate: '2026-03-23'
4+
author: Ken Jin
5+
description: "A look at Python's JIT in 3.15a7."
6+
tags:
7+
- JIT
8+
- performance
9+
published: true
10+
---
11+
12+
This was [originally posted](https://fidget-spinner.github.io/posts/jit-on-track.html) on [Ken Jin's Blog](https://fidget-spinner.github.io/).
13+
14+
---
15+
16+
![JIT performance as of 17 March (PST). Lower is better versus interpreter](brrr-20260317.png)
17+
(JIT performance as of 17 March (PST). Lower is better versus interpreter. Image credits to [doesjitgobrrr.com](https://doesjitgobrrr.com/)).
18+
19+
Great news---we've hit our (very modest) performance goals for the CPython JIT over a year early for macOS AArch64, and a few months early for x86_64 Linux. The 3.15 alpha JIT is about **11-12%** faster on macOS AArch64 than the tail calling interpreter, and **5-6%** faster than the standard interpreter on x86_64 Linux. These [numbers](https://doesjitgobrrr.com/run/2026-03-17) are geometric means and are preliminary. The actual range is something like a **20% slowdown to over 100% speedup** (ignoring the ``unpack_sequence`` microbenchmark). We don't have proper free-threading support yet, but we're aiming for that in 3.15/3.16. The JIT is now back on track.
20+
21+
**I cannot overstate how tough this was**. There was a point where I was seriously wondering if the JIT project would ever produce meaningful speedups. To recap, the original CPython JIT had practically no speedups: 8 months ago I posted a [JIT reflections article](https://fidget-spinner.github.io/posts/jit-reflections.html) on how the original CPython JIT in 3.13 and 3.14 was often slower than the interpreter. That was also around the time where the Faster CPython team lost funding by its main sponsor. I'm a volunteer so this didn't affect me, but more importantly it did affect my friends working there, and at a point of time it seemed the JIT's future was uncertain.
22+
23+
So what changed from 3.13 and 3.14? I'm not going to give some heroic tale of how we rescued the JIT from the jaws of failure through our acumen. I honestly attribute a lot of our current success to luck---right time, right place, right people, right bets. I seriously don't think this would've been possible if a single one of the core JIT contributors: Savannah Ostrowski, Mark Shannon, Diego Russo, Brandt Bucher, and me were not in the picture. To not exclude the other active JIT contributors, I will also name a few more people: Hai Zhu, Zheaoli, Tomas Roun, Reiden Ong, Donghee Na, and I am probably missing a few more.
24+
25+
I'm going to cover a lesser talked about part of a JIT: the people, and a bit of luck. If you want the technical details of how we did it, it's [here](https://fidget-spinner.github.io/posts/faster-jit-plan.html).
26+
27+
## Part 1: A community-led JIT
28+
29+
The Faster CPython team lost its main sponsor in 2025. I immediately [raised the idea of community stewardship](https://discuss.python.org/t/community-stewardship-of-faster-cpython/92153). At the time, I was pretty uncertain this would work. JIT projects are not known to be good for new contributors. It historically requires a lot of prior expertise.
30+
31+
At the CPython core sprint in Cambridge, the JIT core team met, and we [wrote a plan](https://fidget-spinner.github.io/posts/faster-jit-plan.html) for a 5% faster JIT by 3.15 and a 10% faster JIT by 3.16, with free-threading support.
32+
A side note, which was less headline grabbing, but vital to the health of the project: was to **decrease the bus factor**. We wanted 2 active maintainers in all 3 stages of the JIT; frontend (region selector), middle-end (optimizer), backend (code generator).
33+
34+
Previously, the JIT only had 2 active recurrent contributors middle-end. Today, the JIT has 4 active recurrent contributors to the middle-end, and I would consider the 2 non-core developers (Hai Zhu and Reiden) capable and valued members.
35+
36+
What worked in attracting people were the usual software engineering practices: breaking complex problems down into manageable parts. Brandt started this earlier in 3.14, where he opened multiple [mega-issues](https://github.com/python/cpython/issues/131798) that split optimizing the JIT into simple tasks. E.g. we would say "try optimizing a single instruction in the JIT". I took Brandt's idea and did this for 3.15. Luckily, I had an easier job as my issue involved converting the interpreter instructions to an easily optimizeable form. To encourage new contributors, I also laid out [very detailed instructions](https://github.com/python/cpython/issues/134584) that were immediately actionable. I also clearly demarcated units of work. I suspect that did help, as we have 11 contributors (including me) working on that issue, converting nearly the whole of the interpreter to something more JIT-optimizer friendly. The core was that the JIT could be broken down from an opaque blob to something that a C programmer with no JIT experience could contribute to.
37+
38+
Other things that worked: encouraging people, celebrating achievements big or small. Every JIT PR had a clear outcome, which I suspect gave people a sense of direction.
39+
40+
The community optimization efforts paid off. The JIT went from 1% faster on x86_64 Linux to 3-4% faster (see the blue line below) over that time period:
41+
42+
![JIT performance vs interpreter during community optimization effort](refcount-jit-vs-interpreter.png)
43+
(Image credits to [doesjitgobrrr.com](https://doesjitgobrrr.com/)).
44+
45+
## Part 2: Lucky bets
46+
47+
### Trace recording
48+
Again, I attribute a lot of this to luck, but during the CPython core sprints in Cambridge, Brandt nerd-sniped me to rewrite the JIT frontend to a tracing one. I initially didn't like the idea, but as a friendly form of spite-driven-development, I thought I'd rewrite it just to prove to him it didn't work.
49+
50+
The initial prototype worked in 3 days, however it took a month to get it JITting properly without failing the test suite. The initial results were dismal---about 6% slower on x86_64 Linux. I was about to ditch the idea, until a lucky accident happened: I misinterpertered a suggestion given by Mark.
51+
52+
Mark had suggested earlier to thread the dispatch table through the interpreter, thus having two dispatch tables in the interpreter (one normal interpreter, and one for tracing). Mark suggested we should have the tracing table be tracing versions of normal instructions. However, I misunderstood and came up with an even more extreme version: instead of tracing versions of normal instructions, I had only one instruction responsible for tracing, and all instructions in the second table point to that. Yes I know this part is confusing, I'll hopefully try to explain better one day. This turned out to be a really really good choice. I found that the initial dual table approach was so much slower due to a doubling of the size of the interpreter, causing huge compiled code bloat, and naturally a slowdown. By using only a single instruction and two tables, we only increase the interpreter by a size of 1 instruction, and also keep the base interpreter ultra fast. I affectionally call this mechanism dual dispatch.
53+
54+
There's a lot more that went into the design of the trace recording interpreter. I'm tooting my own horn here, but I truly think it's a mini work of art. It took me 1 week to iterate on the interpreter until it was overall faster. It went from 6% slower to roughly no speedup after using dual dispatch. After that, I stamped out a bunch of slow edge cases in the tracing interpreter to eventually make it 1.x% faster. Tracing the interpreter itself is only 3-5x slower by my own estimations than the specializing interpreter. Key to this is that it respects all normal behavior of the specializing interpreter and mostly doesn't interfere with it.
55+
56+
Just to give you an idea of how much trace recording mattered: it increased the JIT code coverage by 50%. This means all future optimizations would likely have been around 50% less effective (assuming all code executes the same, which of course isn't true, just bear with me please :).
57+
58+
So I have to thank Brandt and Mark for leading me to stumble upon such a nice solution.
59+
60+
### Reference count elimination
61+
62+
The other lucky bet we made early on was to try reference count elimination. This, again, was work originally by Matt Page done in CPython bytecode optimizer (more details in previous blog post on optimization). I noticed that there was still a branch left in the JITted code per reference count decrement even with the bytecode optimizer work. I thought: "why not try eliminating the branch", and had no clue how much it would help. It turns out a single branch is actually quite expensive and these add up over time. Especially if it's >=1 branch for every single Python instruction!
63+
64+
The other lucky part is how easy this was to parallelize and how great it was a tool to teach people about the interpreter and JIT. This was the main optimization that we directed people to work on in the Python 3.15 JIT. Although it was a mostly manual refactoring process, it taught people the key parts they needed to learn about the JIT without overhwhelming them.
65+
66+
## Part 3: A great team
67+
68+
We have a great infrastructure team. I say this partly in jest, because it's one person. In reality, our "team" is currently 4 machines running in Savannah's closet. Nevertheless Savannah has done the work equivalent of an entire infrastructure team for the JIT. The JIT could not have progressed so quickly if we had nothing to report our performance numbers. Daily JIT runs have been a game changer in the feedback loop. It helped us catch [regressions](https://github.com/python/cpython/pull/143268) in JIT performance, and lets us know our optimizations actually work.
69+
70+
Mark is technically excellent, and I think he knows the Internet gives him too much praise already so I'm not going to say anything more here :).
71+
72+
Diego is also great. He's responsible for the JIT on ARM hardware, and also has recently started work on making the JIT friendly to profilers. I cannot overstate how hard of a problem this is.
73+
74+
Brandt laid the original foundation for our machine code backend, without which we'd have new contributors writing assembler, which probably would've put more people off.
75+
76+
## Part 4: Talking to people
77+
78+
I also want to encourage the idea of talking to people and sharing ideas.
79+
80+
A shoutout to CF Bolz-Tereick, who taught me a lot about PyPy. I spent a few months looking at PyPy's source code, and I believe this made me a better JIT developer overall. CF was very helpful when I needed help.
81+
82+
I'm also part of a friendly compiler chat with Max Bernstein, without which I'd likely have lost motivation for this a long time ago. Max is a prolific writer, and a friendly compiler person.
83+
84+
Ideas don't exist in a silo. I suspect I became better at writing JITs thanks to hanging out with a bunch of compiler people for some time. At the very least, looking at PyPy has broadened my view!
85+
86+
# Conclusion
87+
88+
People are important, and with some luck, [JIT go brrr](https://doesjitgobrrr.com/).
457 KB
Loading
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
title: 'Python 3.15.0a8, 3.14.4 and 3.13.13 are out!'
3+
publishDate: '2026-04-07'
4+
author: Hugo van Kemenade
5+
description: 'A final alpha and two bug fixes are awaiting your upgrade.'
6+
tags:
7+
- releases
8+
published: true
9+
---
10+
11+
## Python 3.15.0 alpha 8
12+
13+
*This is an early developer preview of Python 3.15*
14+
15+
https://www.python.org/downloads/release/python-3150a8/
16+
17+
### Major new features of the 3.15 series, compared to 3.14
18+
19+
Python 3.15 is still in development. This release, 3.15.0a8, is the final planned alpha release.
20+
21+
Alpha releases are intended to make it easier to test the current state of new features and bug fixes and to test the release process.
22+
23+
During the alpha phase, features may be added up until the start of the beta phase (2026-05-05) and, if necessary, may be modified or deleted up until the release candidate phase (2026-07-28). Please keep in mind that this is a preview release and its use is **not** recommended for production environments.
24+
25+
Many new features for Python 3.15 are still being planned and written. Among the new major new features and changes so far:
26+
27+
* [PEP 810](https://docs.python.org/3.15/whatsnew/3.15.html#whatsnew315-lazy-imports): Explicit lazy imports
28+
* [PEP 814](https://docs.python.org/3.15/whatsnew/3.15.html#whatsnew315-frozendict): `frozendict` built-in type
29+
* [PEP 799](https://docs.python.org/3.15/whatsnew/3.15.html#whatsnew315-sampling-profiler): A new high-frequency, low-overhead, statistical sampling profiler and dedicated profiling package
30+
* [PEP 798](https://docs.python.org/3.15/whatsnew/3.15.html#whatsnew315-unpacking-in-comprehensions): Unpacking in comprehensions with `*` and `**`
31+
* [PEP 686](https://docs.python.org/3.15/whatsnew/3.15.html#whatsnew315-utf8-default): Python now uses UTF-8 as the default encoding
32+
* [PEP 728](https://peps.python.org/pep-0728/): `TypedDict` with typed extra items
33+
* [PEP 747](https://docs.python.org/3.15/whatsnew/3.15.html#typing): Annotating type forms with `TypeForm`
34+
* [PEP 782](https://docs.python.org/3.15/whatsnew/3.15.html#whatsnew315-pybyteswriter): A new `PyBytesWriter` C API to create a Python bytes object
35+
* [PEP 803](https://peps.python.org/pep-0803/): Stable ABI for free-threaded builds
36+
* The [JIT compiler](https://docs.python.org/3.15/whatsnew/3.15.html#whatsnew315-jit) has been significantly upgraded, with 6-7% geometric mean performance improvement on x86-64 Linux over the standard interpreter, and 12-13% speedup on AArch64 macOS over the tail-calling interpreter
37+
* The official Windows 64-bit binaries now [use the tail-calling interpreter](https://docs.python.org/3.15/whatsnew/3.15.html#whatsnew315-windows-tail-calling-interpreter)
38+
* [Improved error messages](https://docs.python.org/3.15/whatsnew/3.15.html#improved-error-messages)
39+
* <small>(Hey, **fellow core team member,** if a feature you find important is missing from this list, let Hugo know.)</small>
40+
41+
The next pre-release of Python 3.15 will be 3.15.0b1, scheduled for 2026-05-05.
42+
43+
### More resources
44+
45+
* [Online documentation](https://docs.python.org/3.15/)
46+
* [PEP 790](https://peps.python.org/pep-0790/), 3.15 release schedule
47+
* Report bugs at [https://github.com/python/cpython/issues](https://github.com/python/cpython/issues)
48+
* [Help fund Python directly](https://www.python.org/psf/donations/python-dev/) (or via [GitHub Sponsors](https://github.com/sponsors/python)) and support [the Python community](https://www.python.org/psf/donations/)
49+
50+
51+
## Python 3.14.4
52+
53+
Python 3.14.4 is the fourth maintenance release of 3.14, containing around 337 bugfixes, build improvements and documentation changes since 3.14.3.
54+
55+
https://www.python.org/downloads/release/python-3144/
56+
57+
## Python 3.13.13
58+
59+
Python 3.13.13 is the lucky thirteenth maintenance release of 3.13, containing around 200 bugfixes, build improvements and documentation changes since 3.13.12.
60+
61+
https://www.python.org/downloads/release/python-31313/
62+
63+
64+
## Enjoy the new releases
65+
66+
Thanks to all of the many volunteers who help make Python development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organisation contributions to the [Python Software Foundation](https://www.python.org/psf/donations/).
67+
68+
Your release team,<br>
69+
Hugo van Kemenade<br>
70+
Thomas Wouters<br>
71+
Ned Deily<br>
72+
Steve Dower<br>
73+
Łukasz Langa
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: Rust for CPython Progress Update April 2026
3+
publishDate: '2026-04-08'
4+
author: Emma Smith
5+
description: "Rust for CPython project status update April 2026"
6+
tags:
7+
- Rust
8+
published: true
9+
---
10+
11+
> This post has also been shared on [discuss.python.org](https://discuss.python.org/t/rust-for-cpython-progress-update-april-2026/106895).
12+
13+
---
14+
15+
We (the Rust for CPython community) wanted to provide an update on where the project is and our current plans from now to a Python Enhancement Proposal (PEP) for introducing Rust into CPython.
16+
17+
## Recent work
18+
19+
Since the [pre-PEP thread](https://discuss.python.org/t/pre-pep-rust-for-cpython/104906), we’ve been working on making the reference implementation build system more robust across the platforms CPython supports. We’re now successfully building CPython with Rust in our fork’s CI on all tested platforms.
20+
21+
We’ve also had a number of productive discussions with the Rust team, who have been incredibly generous to meet with us to discuss the needs of the CPython project and how best to address issues we face with integrating Rust with CPython. I’m incredibly grateful to everyone who has joined those meetings.
22+
23+
We’ve also had some discussions about the design of a Rust API for CPython. You can see [issues tagged api-design](https://github.com/Rust-for-CPython/cpython/issues?q=is%3Aissue%20state%3Aopen%20label%3Aapi-design) which cover the critical components of the API design. We’d love to get more input on designing the Rust API, so please see below about contributing if you are interested in working with us on the Rust API. As a reminder, this API will remain internal until a later PEP stabilizes it and makes it public.
24+
25+
## Roadmap to a PEP
26+
27+
Since the pre-PEP, we’ve decided that we will be targeting Python 3.16 rather than 3.15 as the first Python version to include Rust code. This gives us a year to make the reference implementation the best it can be and plenty of time for discussion of the PEP.
28+
29+
The below timeline is subject to change, but covers a rough plan of what and when we hope to accomplish things:
30+
31+
- March
32+
- Done! ~~Finish the build system work, ensuring platforms tested in CPython CI are green~~
33+
- April
34+
- Start planning the internal Rust API design
35+
- Select a single extension module to have a Rust implementation in 3.16
36+
- May
37+
- Finalize a plan for the internal Rust API design
38+
- Start implementing the internal Rust API
39+
- Sprint at PyConUS on the internal Rust API and the extension module
40+
- June
41+
- Start writing the PEP
42+
- July
43+
- Finalize the PEP draft
44+
- Submit the PEP and begin discussion
45+
46+
We recognize introducing Rust is a significant change, and expect the PEP discussion to be lengthy, so we want to make sure there is ample time to discuss it prior to [3.16 beta 1 in May 2027](https://peps.python.org/pep-0826/#schedule).
47+
48+
## Contributing
49+
50+
Interested in contributing to the Rust for CPython project? Please join [our Discord](https://discord.gg/2pw3YSDscP)! We have meetings every Monday at 12:00PM PDT to discuss the project. We’d love to have more folks join those meetings and work with us on Rust for CPython!

keystatic.config.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const knownAuthors = [
2323
"Michael Markert",
2424
"Mike Driscoll",
2525
"Philip Jenvey",
26+
"Emma Smith",
2627
];
2728

2829
const knownTags = [
@@ -37,6 +38,7 @@ const knownTags = [
3738
"contributors",
3839
"buildbot",
3940
"history",
41+
"Rust",
4042
];
4143

4244
const referenceComponents = {

0 commit comments

Comments
 (0)