There's a difference between dead (i.e. "unmaintained") and low activity ("not under active development"). From what I can see PyPy is in the latter category (and being in that category does not mean it's going to die soon), so choosing to claim it is unmaintained is notable.
I'd genuinely be curious what fraction of those changes actually requires porting to other Python implementations. The free-threading changes are inherently interpreter specific, so we can ignore those. A significant change in Python 3.12 is dropping "dead batteries", so that can be ignored as well. From what I can see, the main language changes are typing-based (so could have parser implications), and the subinterpreter support being exposed at the Python level (I don't know whether that makes sense for PyPy either). I think this hints that while certain area of Python are undergoing larger changes (e.g. typing, free-threading), there is no obvious missing piece that might drive someone to contribute to PyPy.
Also, looking at the alternate (full) interpreters that have been around a while, PyPy is much more active than either Jython or IronPython. Rust-python seems more active than PyPy, but it's not clear how complete it is (and has going through similar periods of low activity).
Would I personally use PyPy? I'm not planning to, but given how uv is positioning itself, this gives me vibes of youtube stating it will drop IE 6 at some unspecified time in order to kill IE 6 (see https://benjamintseng.com/2024/02/the-ie6-youtube-conspiracy...).
The problem is the million small paper cuts. The stdlib changes are not all in pure python, many have implications for compiled modules like _ssl. The interpreter changes, especially compatibility with small interpreter changes that are reflected in the dis module, also require work to figure out
I don't know about that. For me, f-strings were the last great quality-of-life improvement that I wouldn't want to live without, and those landed in Python 3.6. Everything after that has not really made much of a difference to me.
This reads like you think that "major" version bumps should ony happen when things make a big difference to you personally. At least that's where you land when you follow the logic of your statement. I think you may overrate the importance of your particular use case, and misunderstand what GP meant by "major".
The gist of what GP meant is that Python does not exactly follow SemVer in their numbering scheme, and they treat the middle number more like what would warrant a major (left-most) number increase in SemVer. For example, things will get deprecated and dropped from the standard library, which is a backwards-incompatible change. Middle number changes is also when new features are released, and they get their own "what's new" pages. So on the whole, these middle-number changes feel like "major" releases.
That being said, the Python docs themselves [0] call the left-most number the "major" one, so GP is not technically correct, while I'd say they're right for practical, but easier to misunderstand, purposes.
> A is the major version number – it is only incremented for really major changes in the language.
> B is the minor version number – it is incremented for less earth-shattering changes.
> C is the micro version number – it is incremented for each bugfix release.
> That being said, the Python docs themselves [0] call the left-most number the "major" one, so GP is not technically correct, while I'd say they're right for practical, but easier to misunderstand, purposes.
That's ultimately the point I was trying to make; my inner pedant can't help but feel the need to push back on people using versioning terminology inconsistently, but in practice I don't think it really made much of a difference in this case.
Oh, you are right, I forgot that "major version" is a technical term and incorrectly read it as "For Python, 0.1 increases make a big difference". My bad!
If you want your code to run, you need a python interpreter that supports the newest of your dependencies. You may not use features that came after 3.6 (though you obviously do), but even if just one dependency or sub-depdendency used a python 3.10 specific feature you now need interpreter at least this new.
That is true, and it is also a huge pet peeve of mine. If more library maintainers showed some restraint it using the newest and hottest features, we'd have much less update churn. But on the other hand, this is what keeps half of us employed, so maybe we should keep at it after all.
They are de facto semantic major versions - think of recent-ish additions like f-strings and match-case (3.7 and 3.11, I think), you'd get a syntax error in an older parser. PyPy targeting 3.9 for example would would support f-strings but not match-case.
Or at runtime, you can import things from the standard library which require a minimum 3.x. - .x releases frequently if not always add things, or even change an existing API.
> They are de facto semantic major versions - think of recent-ish additions like f-strings and match-case (3.7 and 3.11, I think), you'd get a syntax error in an older parser. PyPy targeting 3.9 for example would would support f-strings but not match-case.
Are you saying that you'd get an error using the new feature on an old version, or that code that used to parse on old versions would not longer work on the newer version? The former is pretty much a textbook example of a minor version update in "traditional" semver; a single new API function is enough to potentially make new code not work on old versions, since any calls to that function will not work on versions predating it. The latter is what would constitute a "breaking change" in semver; old code that used to work can't be made to no longer work without a major version bump.
I say "traditional" semver because in practice it seems like there are fairly few cases in which people actually seem to fully agree on what semver means. I've always found the "official" definition[1] to be extremely clear, but from what I can tell most people don't really adhere to it and have their own personal ideas about what it means. I've proposed things in projects that are fully within both the letter and spirit of semver quite a few times over the years only for people to object on the basis that it "isn't semver" because they hadn't fully read through the description before. Typically I'll mention that what I'm suggesting is something that semver allows and bring up the page and show them the clause that specifically allows what I'm saying but clarify that I recognize we still might not want to do it for other reasons, and the other person will end up preferring to stick with their initial instinct independent of what semver actually says. This is totally fine, as semver is just one of many versioning scheme and not some universal optimum, but my point is that it's probably more confusing for people to use the same term to describe fairly inconsistent things.
True - I don't think I really had my head screwed on there. It just 'feels different' because it's language level, the actual syntax, I suppose, but no - you're right.
It’s been a lot longer than that. There was a reasonable sized effort to provide binaries via conda-forge but the users never came. That said, the PyPy devs were always a pleasure to work with.
The problem is that it is lagging behind enough that it is falling out of the support window for a lot of libraries.
Imagine someone releases RustPy tomorrow, which supports Python 2.7. Is it maintained? Technically, yes - it is just lagging behind a few releases. Should tooling give a big fat warning about it being essentially unusable if you try to use it with the 2026 Python ecosystem? Also yes.
3.11 still has 2 years of active security patches, and has most of the modern python ecosystem on tap. That is a whole different ballgame than stuff stuck in the pre-split 2.x world