This way I can easily write inlined functions with proper C speed, in a Python esque language.
Reasons why I rarely use Cython without this:
- unmodified Python code running in Cython is often faster, but not that much. 50% or so is my rule of thumb.
- but the development style is very different for Cython and Python, adding a lot of impedance. Eg reloading doesn’t quite work, profiling is different, you need a build directory and a build step at deployment etc.
- Cython proper is different enough and I’d argue unintuitive enough that if I have to have all these things in place, I might as well wrap my function in Rust.
Such a decorator would give you a low friction way to make things faster when you need it, with scope for making it much faster via all the funny Cython, while keeping Python-esque semantics, in particular "development semantics".
I think it would require some language modification since Cython was definitely a superset of Python; I think some of that syntax has been streamlined, but maybe still a strict superset.
On another note, I'm working on a (big) PEP for python, and looking for maintainers and sponsors (as per python's rules). Do someone know where I could find such amazing persons? (I already have the code, works in cython,graalVM and pypy, and it's kind of a big change but I believe it will help a lot the language)
A pain point that is big enough that at least two programming languages, Julia and Mojo, were created to move beyond it.
Which would not even be an issue, if Lisp, Scheme and Prolog had not lost their aura among AI devs.
https://github.com/py2many/py2many
https://github.com/adsharma/fquery/blob/main/tests/django_example_model.pyFolks, numba is great. To first approximation: write your python function to "look like C"[1] and work over the numpy arrays you probably already have and understand, put a "@jit" decorator on it, and you're done. It JITs and runs your code natively at native performance.
With some extra effort, there are features for SIMD vectorization and thread parallelism, and even GPU backends (that, full disclosure, I've been pretty frustrated by -- but they do work).
[1] Which is to say, don't touch Python interpreter data structures. No dicts or objects or lists or strings, etc... If you're bound by the interpreter[2] you're bound by the interpreter and nothing is going to help you.
[2] A corrolary here is that the kind of C code numba is NOT good for is "following pointers between structs", which is something that can't be expressed in either python or numpy.
* Typing is a non-obligatory add-on to the syntax
* SQLAlchemy and other ORMs override basic operators like "=" and employ metaclass programming heavily to create Python-like SQL query builders
* Pytest rewrites all the assertions as it side-steps bytecode generation (so your .pyc files are different than what they would be without pytest)
* Many libraries depend on monkey-patching live library calls, including ones to external dependencies
* The way async was added in is another bolt-on where the same code behaves differently in different contexts
* Decorators can introduce any side-effect you imagine, and nobody (including core libraries) follow the golden rule of "don't do, only decorate"
* Many debugging and profiling mechanisms (including REPL) depend on these properties to function — including observability tooling like Sentry, Datadog etc.
...
JavaScript never had that level of flexibility (for better and for worse), and by extension, it's easier to build an alternative implementation and keep it compatible with the rest of the world that claims to be JavaScript.If all python had was __slots__ then we would not be struggling to JIT python.
Tight numerical loops is where the JIT adds performance.
Most performance sensitive features are already available in python between numpy, numba and Cython without really leaving the language core.
You'll mostly be speeding up the slow parts of python, not supercharging the fast parts.
There are already many way of addressing Python performance (leaving aside whether Python is a good choice if performance matters) such as Cython, Numba, Pypy and C extensions.
Not to say that the technical objections were without merit, they likely very much weren't, and the debugger and instrumentation support and maintenance work sounds fairly painful on its own.
If having to put all that in writing and get a bunch of people to agree feels too burdensome to you, maybe that’s a sign that you would be happier working on something other than core changes to the world’s second most popular programming language.
(edit: That wasn’t meant to be a jab at the core developers working on the JIT. Based on what’s in the public discussion threads, they have been handling things very well throughout the process. It’s unfortunate that the SC let the project get this far before realizing the project had grown well beyond its original PIP’s mandate, and I’m sure that is deeply frustrating to the people leading the project. I know I would not be handling the setback nearly as gracefully as they are.)
As they themselves pointed out, the problem isn’t that there’s anything wrong with an open-ended experiment. It’s just that open-ended experimentation doesn’t belong in main, of all places. They have an ongoing duty to ensure that a critical piece of global infrastructure remains stable and trustworthy to consider.
The scope of a JIT is the entire python runtime. Not at the beginning, it can be more narrow, but certainly it can evolve to cover everything. JITs touch everything.
> success criteria
Impossible to measure. JITs don't universally make things faster and unless the SC was willing to accept "some programs will see around x% improvement" then it would be impossible to actually give them the criteria they want. There's a reason C++ compilers and their optimizations aren't defined by the ISO committee.
> support plan
Like most JITs, support for a JIT is an ongoing and ever evolving process. What's needed depends entirely on what's needed today. You usually need more than 1 or 2 dev working on it, which may be the issue here.
> It’s just that open-ended experimentation doesn’t belong in main, of all places.
Very strong disagree. That's simply the nature of performance optimizations for JITs. They belong on main because new optimizations and heuristics will always be generated. The role of doing a compiler is a long term experiment in performance, seeing what your runtime is currently doing and how it's being used and tweaking it to work better.
pypy isn't in a worse place because it's been running a longterm performance experiment.
> They have an ongoing duty to ensure that a critical piece of global infrastructure remains stable and trustworthy to consider.
None of the things mentioned actually do that, other than perhaps a support plan. There are plenty of critical infrastructure projects who all can manage to develop JITs. Python is the special snowflake that has decided to do JIT development incorrectly.
This is a runtime optimization/implementation detail. It's foolish to send it through a committee approval process. That's why you won't be able to find a single language with a JIT or advanced optimizations that has do it by committee.
Perhaps these priorities were always irreconcilable.
Perhaps that’s why the existence of competing Python JIT projects that weren’t trying to commit directly into CPython’s main branch kept coming up in the conversation.
> This is a runtime optimization/implementation detail.
I view JITs as a critical architectural component. Like you said, it impacts the whole system. Optimization and implementation details don't usually do that.
It’s kind of wild how nice Python’s C extension system, which enables basically zero cost interop with native code, is for certain purposes. It supports a situation that’s comparable to the games industry’s tradition of putting a Lua or Lisp tip on top of a C++ iceberg.
Bureaucracy doesn't definitionally mean Kafkaesque. It's popular to hate on it, but good or neutral bureaucracy does exist.
In this case a single committee directly engaged with both core developers and the community, through a fairly open process, explicitly bent several of their own official rules to suit the occasion, and indicated cases where further flexibility might be needed depending on how things develop.
I would call that a pretty stellar example of non-bureaucratic governance.
It’s true that that decision didn’t involve everybody getting their way. But that’s not organizational hell, that’s just organization. If you don’t want to contend with other people’s competing interests, the solution to that is solo development.
HN when an organization achieves its intended goals: this can't be bureaucracy because it's good.
In this case, it seems like the human bureaucracy made wise and measured decisions to contain the software bureaucracy. They made reasonable requests to clarify the scope and impact of a major, major core feature. The proposers didn't feel like that was doable, so a complexity nuke was avoided.
A bit like Chrome there's a fully open source version and a proprietary version with a few extra bells and whistles, but the latter is entirely free for both open and commercial usage (you can't redistribute it for a fee). So you may as well use it.
It has other interesting features
• Scalable pauseless GC
• Single binary distribution of Python programs (like Go)
• Fancy and optimized interop with other languages including Java, JavaScript, Kotlin, Ruby and any other Truffle language.
• Supports native extensions. Tested and works with common libs like SciPy, NumPy, PyTorch, Pandas etc: https://graalpy.org/python-developers/compatibility/
• They're working on a GIL-free mode
In recent weeks there has been a release of a new web framework for Python that only runs on GraalPy, called Pyronaut (https://pyronaut.io/). It takes advantage of JVM interop to expose the Micronaut framework, which is similar to Spring for those who know it. Thanks to the JIT and well optimized base libraries it runs extremely fast, being about 3x faster than FastAPI+Granian, or 7x faster than Flask+Gunicorn and having many more features.
https://www.youtube.com/watch?v=zo6L7bxn4OY
(that was presented at Devoxx but the Pyronaut devs will start touring Python specific conferences soon)
So although CPython may not have made it past the JIT milestone, that doesn't mean Python as a language or community has to fail it. It does require openness to alternative implementations, but historically Pythonistas have been fairly good about that (e.g. Pypy was embraced back when it was more active).
This stuff does require you to accept that it's made by Oracle, but as it's open source, that should be OK.
Disclosure: I sit next to some of the people who work on this stuff.
They are Python libraries. Don't make the mistake of screwing up the cause and effect here. C, Rust etc - those are the replaceable parts of the chain. There is an official C++ pytorch library and virtually nobody uses it for ML Research. People want to code in python and build those libraries so they can.
I think if the Python community wants an implementation that has a proven JIT and where the remaining work is easily scaled compatibility testing, then there's one available and ready. Whether they're calling into C or Rust or FORTRAN or Java shouldn't make a big difference in principle.
How long does that take?
https://pyronaut.io/performance/
> Latency lines come from the load ramp (+25% per 15-second step); throughput from 45-second validation steps (+2% each) after a 180-second warm-up. Each framework ran twice and we show its best run. No profilers were attached.
So that's a "realistic" web serving benchmark if you're willing to grant the use of a GraalPy-optimized framework rather than Flask/FastAPI.
Warmup times for other benchmarks are currently quite unstable because there's a big focus on interpreter performance at the moment, which is one of the main influences on warmup. There's a blog post here from August about how the compiler is being taught to recognize and optimize bytecode interpreter loops, to get results that normally require handcrafted assembly:
https://medium.com/graalvm/escaping-the-giant-switch-dec20b5...
So as you know already, warmup was historically a weakness of PE based stuff - although in this case the fair comparison is with CPython which never warms up at all - but a fast interpreter will make a big difference. In some benchmarks the GraalPy interpreter is already faster than the CPython interpreter, which is heavily optimized.
Are the JIT developers the same people who were working on Faster CPython at Microsoft? No surprise that they don't have the same amount of energy to dedicate to the JIT now that it's gone from a full-time job to a hobby project.
I wouldn't be surprised if they all went nodejs instead :/
Python is a mature production language with a lot of users. Even before it was huge - like 20 years ago when I was in college - getting a small backwards compatible API change into a python extension module (gnu readline in my case) required convincing GvR personally that the API change was necessary.
Every JIT attempt I've seen for python just tries to cut too deep in the first pass, and scope themselves too large.
I believe any successful attempt at optimizing python performance from JIT will FIRST start with a 100% semantically compatible hidden type model for optimizing object property access and method dispatch.
The single biggest performance delta in most dynamic language jits come from that, not from optimizing guards off of bytecode operations or from compiling to machine code. It's from converting hashtable lookups into constant-time guard + offset lookups.
The hidden type model is also a hard nut to crack. It needs to perserve dict semantics which have very dynamic behaviour via the various `__*__` methods, and handle exotics scope objects since scoped name lookups are the most common ones which have their own exotic behaviours (I remember python providing some ability for callee frames to inspect caller scopes in some limited ways).
Python already does it in a lot of cases, see opcode specializations like LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_SLOT.
More digging led to this: https://peps.python.org/pep-0659/ which seems to be what the effort is organized around?
Python's object semantics are broadly similar to Javascript, bar the prototypical inheritance chain, but with the extra complexity of potentially needing to handle dynamic `__*attr__` overrides. Optimizing for this would require a tree of hidden map objects much like JS JIT engines use. I dug around the codebase a while back looking for something like that but didn't find it. `OrderedDict` seemed promising but after more investigation that turned out to just be adding property ordering to dictionaries.
The thing is, you can build that entire hidden type structure out, AND optimize against it, without ever having to mess with things like bytecode replacement. Once you have the hidden type model, you can modify the property lookup algorithm in the VM itself (as in cpython c code) to use some annotation structure hanging off of the bytecode to look up inline caches of type-guarded fastpaths. It would be an optimized fastpath that integrated directly into the C code that interprets the GETATTR opcode.
I don’t really think that’s true or even that relevant , at least in context of classes (especially with slots - the class, by definition, _is_ the “hidden map”) and not generic dicts.
> The thing is, you can build that entire hidden type structure out, AND optimize against it, without ever having to mess with things like bytecode replacement.
Pretty sure the motivation was exactly the opposite - that a simple “if a LOAD_ATTR encounters the same class with slots N times in a row, swap it out for LOAD_ATTR_SLOT with inline cached slot index, and swap back to generic one if something changes” is way easier (both to implement and reason about) than any alternative that’d interact with the object model. (Also it means you skip having to branch between a slow and fast path at all)
> you can modify the property lookup algorithm in the VM itself (as in cpython c code) to use some annotation structure hanging off of the bytecode to look up inline caches of type-guarded fastpaths. It would be an optimized fastpath that integrated directly into the C code that interprets the GETATTR opcode.
Sorry, that sounds a bit vague and not too different from what CPython already is doing.
> Sorry, that sounds a bit vague and not too different from what CPython already is doing.
With slots being available, I can see where I was misled. I went looking for a type structure that modeled the dynamic properties on an object which would be used as a typeguard, but the class itself functions as that if you're restricting the optimization to slotted properties.
Appreciate the clarfication!
https://peps.python.org/pep-3000/ - PEP 3000 says it will be a derived from the Python 2 codebase and not a complete rewrite (referencing Joel Spolsky's views on complete rewrites and Netscape Navigator).
https://peps.python.org/pep-3099/ - PEP 3099 is changes Guido van Rossum rejected from Python 3 (including := as a binding operator), parallel iteration, programmable syntax, parser going beyond LL(1), changing the for/else construct.
https://peps.python.org/pep-3100/ - PEP 3100 is things he set as goals for it, things like all strings are Unicode and byte arrays are a separate type, optional type annotations, 'exec' and 'print' change from statements to functions, None/True/False become keywords, old-style classes are gone, changing inequality comparison from <> to != , require C99, drop BeOS support, drop old standard library modules, and more.
actually, more changes than I remember.
Probably also during the 2 to 3 migration, but that goal appears to have now been abandoned.
I wonder how the authors of other implementations like pypy will be able to keep up as the reference implementation becomes more and more complex.
The problem was he exposed too much of the implementation into the language itself, destroying its ability to be a simple reference implementation that others could re-implement.
Today there are far more people using it, and everyone has a different perspective on what it is. No longer is it a niche glue language, now it's a backbone of AI technology at major tech firms, so it's understandable they'd like it to be faster on its own.
What about the other major change to Python's implementation: free threading? Has it lived up to expectations? I assume it's not also in doubt, despite Guido recently saying "Personally I wish we’d stuck with the GIL"? [0]
[0] https://discuss.python.org/t/pep-805-safe-parallel-python/10...
It boggles my mind that it apparently is the case that such a popular language as Python isn't able to get the resources to do this.
If JIT is different enough in maintenance, security best practices, and consumer use, we don’t have two compilers, we have two different languages.
And that’s the crux of it.
The static + AOT approach has a lot of promise now that type annotations are widely adopted, predictable behavior and good performance on code that is mostly idiomatic Python seem like a good alternative in many situations to the weight of Rust.
> We want the PEP to be clear that it’s ultimately the JIT team’s responsibility to find solutions for these packages and tools, and how to deal with situations where a tool can’t be supported or made to work
Is it just me or is this absurdly impossible, to the point of willfully killing the project? Committing a team of brilliant compiler engineers to doing free consulting ad infinitum for every bit of tooling in the world, however hacked-together?
The alternative would be to have the bravery to say: this is the way forward to keep this language relevant into the future, and as a steering committee we collectively own that some tooling may be out of date. Instead, this is a signal that Python is going to rest on its laurels for a very long time.
Where do we go from here? Microsoft did not continue to finance the Faster CPython project and the current speed gains are good, but not what we hoped.
F# is on the softest side of that, but letting the compiler tell the AI "nope, here's why" seems like a huge win in saving cycles and time.
The downside at first was simply, "how many examples of F# are there to learn from", and early on it showed, but I think that's been long overcome.
And F# is obviously NOT the best example since it's both "soft" on functional purity and niche. I imagine something like haskell is probably doing even better, although I've yet to check that at all (not that I can code haskell but I haven't looked at anecdotes or anything).
I realize this doesn't really help anyone who's grown to love python, and there's surely no perfect language, but just like how the web catapulted javascript, I see a future where the answer isn't "use AI to make python better" so much as "what already works super well with AI, and does it ease the user adoption"
The problem is that Python just isn't going to go fast. There are some languages that may have had more resources poured into them to make them go faster in absolute terms, like perhaps Java. But I don't think there's a single language that has had so many ways of trying to make it go faster given so much effort over so many decades. It's really time to call it... if you have Python code and it's a performance problem, if one of the many many many different solutions aren't adequate for some reason, Python is not going to get any faster than it is today and you're going to have to move off of it.
If you need high performance code, Python is simply not the right answer and you're going to have to skill up. Or accept what you have, which you'll have to decide if that's a viable option. If it's fast enough I don't advocate switching casually. But if it isn't, there isn't a realistic prospect that you're going to wake up in a year or two to a 30x-faster Python. I wasn't terribly convinced by that claim back in the early 2000s, but it hadn't really been tested yet. It has been tested now.
Implementation effort has never been what has held these efforts back. LLM helps with squirting out code, but the hard tasks are benchmarking, profiling, community engagement, knowledge management, and dealing with the hard questions such as whether the change is actually worth the additional complexity.
These concerns won't go away even if we give up on human developers being able to grok the code and instead completely relying on LLMs for coding.
Ruby is on its third (I think?) JIT now? I'm a little surprised, given Ruby's reputation as a wacky "anything goes" language with a very complex grammar, and it makes me wonder why that is? Does it have to do with the design of the runtime itself more than the language semantics? Or is it more incidental, e.g. many popular ibs are C wrappers, already generates bytecode files, and so on.
If the Python steering committee isn't willing to do the same, they'll probably won't get a working JIT any time soon. Developing a JIT externally, or even from a branch, is just too hard.
Why had Python to succeed to Lisp in the AI wave? (rhetoric question)
Since PyPy and GraalPy will never get the love they deserve, I guess there is hope that Julia, Mojo, and the whole Rewrite in Go/Rust keep pushing along then.
Python in itself is poorly suited to ever become performant as it lacks the types required. I imagine that causes some issues for effective jit-ing too.
They had a chance to fix this when adding type annotations, but instead of making it "optional/gradual typing" they opted to make it "documentation or linting support", which is obviously the wrong choice, but there were cultural reasons
I actually expected something good to come out of this, my mistake for trusting Python "engineers". Never again.
Python is my favorite language, but I'm honestly tired of having to rewrite performance bottlenecks in Cython or Rust all the time. When the Faster CPython project started with Microsoft's backing, I was really excited. Mark Shannon had that plan promising huge speedups across a few cycles, and while that clearly turned out to be much harder than anticipated, the team still kept pushing forward to deliver a real JIT.
Seeing all of that get bogged down in committee bureaucracy now is just frustrating.
I have a lot of respect for the core devs and I know maintaining CPython, and it is a time donation job. It isn't easy. But I feel that over-caution and red tape ends up discouraging serious contributions. They are setting an unreasonably high bar for something that would obviously help the entire ecosystem.
Just think about the sheer amount of electricity and compute power being wasted every single day running inefficient Python across millions of machines worldwide.
Python really deserves a proper JIT. I genuinely hope they reconsider this.
PyPy lacks upstream interest, looked like it could have a shot after many years of development but recently NumPy removed support because they just couldn’t fathom how a non-dead project could be a couple of versions behind CPython.
Now the new JIT is dying because of what seems to be a lack of upstream interest. (The things TFA describes as being required are not unreasonable, but not realistic for a necessarily speculative long-running project without wild amounts of committed funding.)
I’m not optimistic.
IIRC Unladen Swallow was, despite the extreme hype, nothing more than the internship project of a couple of students. It died because their internship was over.
Otherwise you're right, though. Lots of CPython alternatives suffer from lack of upstream interest - the Python language designers don't seem very interested in anything other than CPython. In particular, they appear to only consider CPython when adding features to the language. Two examples:
- Requiring `dict`s to be ordered because that's how they work in CPython, without considering how they work in other implementations
- Adding pattern matching syntax that's suitable for CPython's PEG parser, even though it's not LL(1) so can't be parsed by, say, MicroPython
Every single time I remember the first AI wave was done with Lisp and Prolog, both with tooling that supports machine code generation since about 50 years.
That's what's kept the language and ecosystem improving and from becoming a hot mess. If something isn't properly specced then it really shouldn't be in prod. They allowed the experiment in the first place so it'd be easier to gather sufficient data to guide said speccing, but the ball was dropped by the proposers and so the experiment was an ultimate failure (unlike free threading) and prod is now being appropriately cleaned up.
In the remote eventuality that it should actually work and be maintained up to date and secure, I'm sure it will acquire users.
Wrote a parser with a rust compatible pattern matching syntax here:
https://github.com/py2many/spy-ast
Should help both JIT and static translation.
for me it's over for python
Under these premises is very difficult that something not implemented correctly is really exploitable, and moreover it's simple to verify the security of the whole thing.
Opening a JIT, that would mean mapping memory pages as RWX, would open the door to all soft of exploits that now are not really possible.
For JS, your machine running untrusted JS code is the intended use case. In this scenario the JS is sandboxed in whatever JS engine (V8 etc) and does not have access to "dangerous" methods, and the main use case for a JIT vuln is to escape this sandbox to execute code on the host. This applies to regular internet browsing (and visiting potentially malicious sites) and also, e.g., using the built-in browser in a locked down device (such as game consoles) to gain arbitrary code execution.
For Python, this security boundary doesn't exist. I can't really think of a scenario where you would be running potentially malicious Python code in CPython that would need a JIT vuln to escape whatever sandbox it is in instead of, say, calling the functions in Python directly (or using the C FFI to do whatever). I'm sure that in some niche use cases, this scenario might exist, but to me, it seems like the potential attack surface is fairly minimal.
EDIT: Also, I'm pretty sure that Python's copy-and-patch JIT writes code to a writable mapping and then mprotects it to W^X? I don't think it leaves RWX pages lying around at all.
JS has a completely different threat model. And PHP has just been a basketcase from inception.
Can you name some of these JS engine vulnerabilities? And the PHP one had nothing to do with JIT.
https://phrack.org/issues/70/exploiting-logic-bugs-in-javasc...
https://www.sentinelone.com/vulnerability-database/cve-2026-...
https://projectzero.google/2020/09/jitsploitation-one.html
https://www.zerodayinitiative.com/blog/2021/12/6/two-birds-w...
I'll get what I want eventually but I might be retired by then.
On one hand, it seemed like JIT work was really progressing in high gear until SC requested a new PEP. Also unfortunate, as it seemed like part of the hope for the JIT was that it'd counter the performance penalty from free threading.
On the other, it did feel (to me) like with all the fancy (and definitely cool) optimizations it got (automatic refcount operation removal, new type-based specializations, inplace math operations), the macrobenchmark benefits weren't _that_ exciting for a JIT. It definitely has potential for more, maybe with even fancier optimizations like unboxing ints, but the complexity just keeps going up.
> It said that the PEP was "overly optimistic" about user-visible differences with the JIT enabled.
The JIT is technically generated from the same source as the interpreter loop itself, so originally the differences were extremely unlikely, but I imagine the risk just kept going up as new JIT-only paths and optimizations were introduced.
And politically, I feel like SC’s reasoning was just “this side project has landed in main branch almost by accident and has been stewing without oversight ever since, with no stabilization in sight”; and the latest PEP was probably still too vague, with a lot of “here’s more things we can add to the stew” - so I can understand if SC wasn’t satisfied.
JITs are big nasty things that by their nature have to do a lot of things. You are basically saying "Give us a PEP for a new python interpreter and compiler".
What they do is fuzzy by their nature because optimizations are very rarely universally beneficial. It's a game of measuring, looking for regressions, and tackling the biggest problem next for whatever sample applications you have available. You always run into the risk of overfitting on top of all that (You may have made django faster, but you've made flask slower).
This is the sort of thing that, IMO, should not go through the PEP process. It's an implementation detail for the runtime.
Imagine, for example, if the JVM needed a bunch of JEPs for JIT improvements. They'd never get done. Or if any javascript engine needed ECMA acceptance before they could do a new JIT optimization.
They do:
https://openjdk.org/jeps/197
https://openjdk.org/jeps/515
Not every optimization requires a JEP, but certainly something as big as "add or remove a JIT" would 100% require a JEP.
FWIW, I definitely can find a bunch of both PEPs and JEPs for internal optimizations, random examples:
https://peps.python.org/pep-0509/
https://openjdk.org/jeps/147
1. An outsider to the regular OpenJDK dev team proposing an optimization.
2. Advertising for a cool new performance tweak with potentially large impact.
You'll also notice that the JEP descriptions are very different from PEP descriptions.
Probably the largest JEP for the JVM, Valhalla
https://openjdk.org/jeps/401
Does not have the same level of requirements being asked of the Python JIT. Further, it's well understood that this JEP will "live on main" for quite some time in preview before it's accepted and merged.
What the JEP does, instead, is simply describe the feature and potential risks.
The vast majority of JVM optimizations do not get a JEP.
> The vast majority of JVM optimizations do not get a JEP.
In Python too. Still, the JIT really is just a really big thing. I don’t know if there could be a better way to do it, as either 1. You develop it off-branch and… make an enormous PR when you’re done, with risks of getting rejected anyway? Or 2, you allow more experiments on main like Rust, but then you end up with hundreds of minor half-maintained nightly-only features, possibly conflicting with each other, and eventually go through bureaucracy to remove them anyway.
The Java governance allows for a lot more open ended projects with follow ups. Not that it's reckless, Valhalla is proof of that, but rather that once something is good enough they are pretty open to just shipping it as a preview feature and refining until it is worthy of being stable.
That's why, for example, we saw ZGC get merged, and then JDK after JDK seeing continuing development and improvement on ZGC (Or G1 for that matter). These GCs were fairly rough on their first release and now they are pretty much best in class.
I see a Python JIT as the same thing. Delivering the infrastructure for a JIT would need a PIP, but I wouldn't put in things like "acceptance criteria" beyond "doesn't break older code". I would expect such a project to get continual updates without PEPs.
Dunno how much investment is needed into language optimization anymore.