The usual GC tradeoff is between memory and CPU performance.
If you set the memory max high, the GC will run less often, you get less pause time.
So I do not understand why it's a surprise that minimizing the pause time requires more memory. Is it because there is no knob to set either the max pause time or the max memory ?
Because people generally do not understand memory management, and by people I mean majority of programmers, leading to dumb tales about performance of GC vs RAII/manual or even glorifying RC
When GC runs less often, doesn't that rather increase the amount of things needed to be cleaned up _when_ GC finally runs? So actually the GC time _at that point_ should be longer, not shorter, while in total summed up, it should be shorter. Running GC often means cleaning up less stuff for every GC run, so the GC time for each run should be shorter.
I suspect 3.14.4 could have been tweaked slightly to address the issue without a revert - they could have prioritized checking the liveliness of objects sorted by size. I’m pretty sure that would fix the max RSS issue without needing a revert and the people unhappy with 3.14 could keep using 3.13 or switch to 3.14 and simply inject explicit calls to gc.gc().
Figuring out how to measure the size of an object can be tricky of course, but I suspect there’s all sorts of things you could try including figuring out how much memory got deallocated after you gc a cycle and attributing it to where the object got allocated as a heuristic to measure the mean allocation size.
> I suspect 3.14.4 could have been tweaked slightly to address the issue without a revert
I'm sure all the people that have been working on this for years would be interested in your small tweak, that they didn't think of, and would happily accept the PR!
a) do work to reduce issues as they come up
b) appease the vocal complaints
A takes work, guts, and risk. Option b was chosen with the GC work basically saddled with so much process it’s never going to change. Python has a very storied history of being very committee driven design so the committee did the committee thing.
Anyone who’s worked in incident response will tell you why you’re wrong.
Tweaking the GC while the system was functionally broken is the worst time to do it. Correct incident response is revert first, figure out how to fix it later.
The difference being this is not a live system and thus incident response is very different. Applying best practices from incident response to development of a language is simply incorrect
Do you live on a planet where the Python language maintainers are deploying Python into your servers or managing them? Do you live on a planet where a new version of Python being released gets instantly and automatically deployed into your systems without testing and validation?
You are responsible for that, not them. And if Python 3.13 is fine for you and you report a performance regression for 3.14, you can still stay on 3.13. And as you say, it was introduced in a new release. What happens when the other side goes and says “3.14.5 regressed on the GC pause times and my p95 web server latencies went up. Please revert”? At least one side can make the case “performance was changed on a major release of Python boundary” while the other is changing the performance on a minor release boundary. It’s an arbitrary decision that speaks to the politics of the organization and less about a well reasoned technical plan.
Your argument is, frankly, idiotic. If a version of Windows, or any deployed software, has a performance regression, do you consider it “not a live product” because you didn’t personally install it yet?
I really don’t have words. When people bemoan the state of software engineering, your comment here is exactly what they’re talking about.
3.14.5 has a serious performance regression - GC pause times have increased significantly since the entire 3.14 series. This is the problem - you’re arbitrarily putting max RSS of certain workloads over the p95 latency of others. It’s arbitrary and why the worst kind of software engineering that inhibits software progress for the sake of nothing changing.
As for Windows, I think you need a better example. OSes frequently change their performance profile on certain workloads and use more memory. Terrible example.
Also please cool it with the personal insults. They’re not productive and shows you’re trying to win the argument through force and emotion instead of reason.
Snarky comment aside, Python is definitely *not* a "live system". If you had worked with such system before you'd know the world of difference between a version release of "stable" software versus a live platform that cannot fail.
You mean software that has to be deployed locally? Like the example I gave?
> you'd know the world of difference
It's actually worse. The longer you take to get a fixed version out there, the more people will install the buggy version. As distribution is more difficult than just merging a Github PR, that buggy version will live longer on live systems. And before you say "but it's on the developer/DevOps/sysadmin to test," I point you to the countless CVEs where this didn't happen.
Knowing this is the situation, it's unconscionable to leave a faulty build on live for longer than necessary, when you can rollback the change with limited risk.
I do find the BDFL approach much better for language design. You might disagree with the direction of the language, but there is usually a "philosophy" or "taste" driven by one person that tends to be consistent over time.
In fact, I think Guido himself resigned due to the experience he had trying to get a PEP through the committee.
> In fact, I think Guido himself resigned due to the experience he had trying to get a PEP through the committee.
If you're referring to the steering council, that group was created in response to Guido stepping down.
He stepped down partly in response to the changing nature of online discussions around changes to the language. He just didn't want to be at the center of every polarizing discussion anymore. I think he also recognized that the transition needed to happen at some point, and that was as good a time as any.
Because it's an implementation detail, not a change to the language itself. Similarly, when they re-implemented the dict type to preserve insert order, they also introduced it without a pep, because it was a side-effect of an implementation detail. Only later they decided people are so likely to depend on this, that they formalized it through a PEP.
Do people use python for new projects apart from ML stuff which hasn't moved to all-native yet?
My experience with Python is a really bad one for professional work: it's chaotic and slow, and has by far the worst versioning and packaging story of any mainstream language, yet its proponents keep praising it in denial.
I guess Python is an ok target for agentic coding, but my god do look Claude's commit messages pretentious, with code bases quickly heading into absolute unmaintainability. At least it had found gross JS injection vectors in a Django app that really shouldn't have made it through a code review, architecture level as they were, but oh well. A mature Django app is also not a nice dev experience IMO, with tons of implicit behavior all over the place encoded in a mix of magic filenames, database naming conventions, and URL routing quickly descending into regexp hacks.
> My experience with Python is a really bad one for professional work: it's chaotic and slow, and has by far the worst versioning and packaging story of any mainstream language, yet its proponents keep praising it in denial.
Some people just don't have the experience you do, "its proponent keep praising it in denial", can we have a better level of debate, come on now.
The slowest of all dynamic scripting languages. Breaking ABI's and API's left and right all the time. Not able to implement basic performance optims. Their infrastructure (pip) getting worse and worse, getting everyone to install private venv's for every app, leading to missing security updates, because updates just break everything.
> Their infrastructure (pip) getting worse and worse
Hi, I'm a pip maintainer, can you please report any issue you think is happening in recent versions of pip: https://github.com/pypa/pip/
I particularly work on performance and stability and think we've been making big strides over the last two years
> getting everyone to install private venv's for every app, leading to missing security updates, because updates just break everything.
venv's stop your OS tooling from breaking, Linux distro maintainers pushed Python packaging to not allow installing into the system packages by default, and they weren't wrong.
All these other problems are solved with proper use of a lock file (which are now standardized, and you can generate and install from them in the latest version of pip), and/or use a project tool (uv, poetry, etc.).
Yeah I still use Python. I've been using it for a long time, I can get stuff done quickly with it, but I feel the same way you do to a big extent. Not sure what to use instead. I hate anything having to do with Javascript even though some parts of the JS world beat Python hollow (it's the other parts that are even worse than Python). Golang? Rust? Both too low level. I do use C++ (also low level) when I need something to run fast, but it's not the first stop. Erlang/Elixir? I like Erlang (haven't used Elixir) but it's too small a world and I'd want something with a serious type system if I'm gonna change languages. Haskell? Too much headache to do even simple things, such as logging. Scala? The bureaucracy of Java with the headaches of Haskell. OCaml? Maybe underrated and I should look into it more, but again it seems like Haskell's poorer cousin. I'm sure I'm overlooking some good ones though.
I don't think it's chaotic. I won't deny it's somewhat slow however usually anything performance sensitive gets shoved in a native code extension anyway.
As for packaging, I haven't had any problems with poetry or uv. The only time I ever had issues was with Windows in corporate environments where wheels were unavailable and it was also basically impossible to get the right toolchain installed for native code. However, not being able to install a compiler is not really a Python problem
Claude Code has a setting to change the git template so it doesn't attribute itself or you can also commit manually.
Half or more of the scientific research community live and breathe Python. Granted, it's Python 3.12, as 3.13 broke most of the C API, and everything COBOL and Fortran just about ground to a halt. But new projects are spun up constantly.
I guess these kinds of priorities are exactly why Python is not my favorite programming language and why you have tens of Python versions installed on any machine. Not to talk about the Python 2 -> 3 drama that was also about fetishising syntax and pureness over pragmatism, installed base, and respect for existing code.
Thanks, what madness. CPython wasn't abandoned in favor of PyPy at the 2 to 3 transition precisely because they wanted to keep the C extensions working. So what do they do next? Break the C extensions. Genius!
I forget who said it, but Python isn't the best at anything but it's decent to good at nearly everything, and that's why it's become so popular.
I do a lot of what I need symbolically in SymPy for dynamics analysis. Past that, I can't speak for it. At University I used Mathematica, but I just don't need all it can do at this point, so once again Python has proven to be "good enough." Matlab will be a similar story (e.g., I've never seen a good alternative to Simulink in Python).
But for everything else outside very specific domain tasks? Mathematica and Matlab are terrible for a lot of reasons. So I'll go out of my way to stay within the Python ecosystem, though I'm not afraid to pull out the specialty tools when I just can't make Python do the task near as well and/or nearly as quickly.
In Pyodide's new versioning scheme, the major version is the concatenated major and minor versions of the corresponding Python release. Pyodide 314 is based on Python 3.14 (which is just the fifteenth minor version of Python 3, counting from zero, and just happens to match the common approximation of pi).
We definitely noticed behavioral differences in 3.14 regarding gc which could show up in particular test suites we have that are purposely ensuring all objects of a certain type were collected after a gc.collect() run. Between this and other issues (changes to the runtime API for typing, the first decently runnable version of free-threading, kind of a longer time for some C-based dependencies to catch up), the transition for my projects (SQLAlchemy) to 3.14 was generally more bumpy than that of say 3.12 or 3.13. will be interesting to see if 3.14.5 allows us to relax some changes we had to make to the test suite.
> Python 3.14.0 introduced a new incremental garbage collector. But reports of higher memory usage caused the Python team to revert the garbage collector changes in 3.14.5.
If they didn't have very good objective reasons the new GC is better, they never should have shipped it. If they do, they should not have reverted the change.
It's better in some ways (order-of-magnitude reductions in pause times were cited) but worse in other ways (higher peak memory usage). That the higher peak memory usage was catastrophic for some users only became apparent through post-release feedback.
They should have shipped it as an addon GC, not enabled by default. One could have turned it on with a command line switch or an env var, just like the Ruby JIT.
It's this sort of stuff that leaves me scratching my head why people like Python so much. I hear them say they prefer the syntax and personally I feel like that's such a small part of the holistic experience of working with any particular language. It's one of the reasons why I gave up on C++ years ago for .NET, the whole system of tooling in .NET has never left me feeling like I was pigeonholed into doing things in stupid, self-flagelating ways. Why should I use a language like C++ that doesn't provide a standard set of package management and build tools? Why should I use a language like Python that feels like it's being designed by amateurs?
I felt like the tooling in Racket, CLisp, and Java were similarly pragmatic and not either religiously devoted to some concept of "backwards compatibility" that I seriously doubt most people actually need, or "ease of use" that actually proves itself to be easy when you consider the not-happy-path of the beginner tutorials. Racket, I didn't continue just because the library ecosystem isn't mature enough to keep up with the latest in databases and other 3rd party services. Java I quit largely because of Oracle and some 2010s problems with stagnation. CLisp mostly because it was too hard to socialize. But never because I thought the core language and tooling were holding me back.
You are right the syntax is a small part of it, but it is more important than you say in this case because Python syntax is one of the things that makes it very readable.
Even if you dislike the direction Python is going in, a lot of what attracted people to Python in the first place is still there. The readability, the large standard library, the huge ecosystem. There are libraries and frameworks for everything: numerical stuff, web development, GUIs etc. Its actually a nice language in itself, just going in the wrong direction now.
If you look at it historically it was really good comparatively. If you compare it to the alternatives available 20 years ago it looks pretty good.
When people say they prefer 'the syntax', I think they usually mean a bit more than just that: at least a fair bit of this is semantics. Python provides a lot of features out of the box, and if you work superficially along the happy path, it is very easy to understand how these work and read code using them.
Take list comprehensions for example. It is mostly syntax: you can do virtually all list comprehensions with just a map and filter function. But the way that it is integrated and presents the code, makes is vastly easier to follow for most developers, which tilts the balancer in favor of doing away with loops and mutable state. Is it syntax that made them do so? Yes, maybe. But its the actual semantics that provide the value.
It's easy to start learning on, or prototype with, and then sometimes momentum just keeps it going. Also it may not really be the best at anything, but it's "pretty good" at just about everything. It's kind of like vanilla ice cream.
Packaging can be irritating although uv takes the sting out a bit.
You are right that outside of verbosity, once you get used to the syntax of a language, the value of one over the other kind of fades.
> Packaging can be irritating although uv takes the sting out a bit.
uv proves the OP’s point. Why couldn’t the core team and the core-adjacent PyPA make a tool as liked as uv, and why is the Python package manager uv written in Rust and not Python?
For the same reason GP posted and half the stdlib is written in C: Python is a language that is almost always good enough, but never really the best (and especially when it comes to performance of complex algorithms).
Because uv itself can fetch a Python distribution. If it's written in Python, it's quite a bit harder to distribute, assuming one of their goals is not to require an existing Python install.
> Why couldn’t the core team and the core-adjacent PyPA make a tool as liked as uv
Incredibly large backward-compatibility burdens [0], internal politics [1] and general institutional dysfunction (no footnote; if you're familiar then you need no explanation, and if you aren't then the less said the better). Nothing to do with Python as a language. Most of the important pieces to get uv-like performance are algorithmic choices, and most of the rest are available as built-in C code in the reference implementation [2].
(Edit: wait, I recognize your username. You should definitely know these sorts of things.)
> why is the Python package manager uv written in Rust and not Python?
Because that's the language that Astral devs like, and because installing Python itself is considered in scope for uv so there would be an intractable bootstrapping issue.
[0]: In particular, the entire model of `setup.py` defining metadata is certifiably insane, especially when you consider the projects that expect to feed that code to Setuptools at build time in order to figure out what version of Setuptools is needed at build time. But this legacy approach is seen as something that absolutely must be guaranteed to work for well beyond even now; even attempts to remove long-deprecated, minor aspects of that functionality end up breaking major projects, including ones that didn't even require a build step in the first place [3].
[1]: Most obviously, GvR not wanting to have anything to do with it when initially approached by the SciPy people in IIRC 2011, leading to the creation of Conda). But a lot of other things, too. The backwards-compatibility issues synergize with this; consider for example the architectural dumpster fire of Setuptools, and the timeline of distutils removal from the standard library.
Any claims that Python has a huge backwards compat mission go right out the window when you consider Python 3. 3 was a perfect chance to fix all of the major problems with Python, problems other languages have solved so there isn't even a need to invent things from scratch. They didn't and that's why the community is still split on adoption.
I have no idea what you're talking about. 3.x objectively did fix the major problems and was not particularly inventive in its approach. The fact that they didn't fix more things all at once — and the fact that they still received massive complaints about supposedly fixing too much — is the origin of that backwards compatibility mission. Actually talking to the devs for any significant length of time makes it clear how much lasting trauma was caused by the change, and how much that cemented pro-backwards-compatibility views. And the community has not been remotely "split on adoption" for years; hardly anyone publishes packages advertised as 2.x compatible any more (e.g. urllib3 gave up almost two years ago). But to the extent that there have been any holdouts at all, it's been people who want ancient systems to work, not people who think that not enough changed to merit upgrading.
Python 3 got very slow update and poor acceptance precisely because it DIDN'T fix major problems, it only tweaked around the edges of minor ones. So people stayed with Python 2 as long as possible. Here's a post from 2014 that I bookmarked and it explains things a decade+ later:
From the link: "You know why I'm not running python 3? Because it doesn't solve a single problem I have. It doesn't solve anyone's problems. It solves imaginary problems, while creating real problems."
Syntax really does matter more than you give it credit for. Were that not the case, I'd expect one Lisp or Scheme dialect or other to take Python's place. Outside of that counterfactual, Python's competition was stuff like Ruby, and it turned out that network effects were also pretty important.
> It's this sort of stuff that leaves me scratching my head why people like Python so much
Because of the libraries, not necessarily the language, which is also quite straightforward. For example we found a niche library that speaks the ISO-TP protocol in Python, which allows us to communicate with vehicle ECUs. That's why people also use C++, even tough I quite doubt it's because they like the language. Add to that that it's also heavily used in embedded programming. Yes, you could call a C/C++ library from another language, depending how well the language can do that.
I prefer Ruby, but Python probably has just about everything one would need. It's also great for data processing. We hardly have anything better than pandas, polars, numpy, scipy in other languages and that:s without even mentioning ML tooling.
Python is mostly about the “batteries included” standard library and what’s becoming nearly standard third party libs, being able to play around in the REPL,
The standard library is full of dead batteries. If the stdlib is so good, why does everyone install requests instead of using the stdlib http client? And why requests or something like it hasn't been adopted into stdlib after so many years of stability?
People mostly defer to requests because they do not track language development closely and because we are creatures of habit.
I try to avoid non-stdlib packages when stdlib will do a good job, but I received negative feedback from people who aren't aware of the updates and couldn't foresee supply-chain attacks.
The current standard library urllib is a refactoring of previous attempts from the 2.x standard library, and urllib.request is just a sub-package. It does not represent adoption of requests; requests builds on urllib3, which was created to fill in gaps in what the standard library provided, and named like that because the 2.x standard library had both a `urllib` and a `urllib2` as they struggled to figure it out.
For a long time, urllib had everything deprecated except for the parsing code which remained relevant as the upstream RFCs have not changed IIRC.
Urllib2 is now also gone and mostly replaced with urllib.request.
It should cover 99% of the use-cases one would use requests for — I am not sure how and why it matters that it is a subpackage and not a top-level package?
This is just a natural evolution of a widely used language where you have to be careful with backwards compatibility.
You are picking one of the weak points of the standard library and an unusually popular replacement (and AFAIK it is built on the standard library). I cannot think of many others that are widely used. Maybe lxml ?
A Python codebase might well use requests, but it will almost always also heavily use the standard library.
> “batteries included” standard library and what’s becoming nearly standard third party libs
Historically, the standard library made sense. And we're talking about a history that stretches back to before Internet connections were ubiquitous, to say nothing of connection speed.
Now the standard library is full of things that they refuse to remove because it would supposedly be too disruptive, but which they would never think of adding today if they weren't already there.
Related. 31 days ago
Reverting the incremental GC in Python 3.14 and 3.15
265 points, 130 comments
https://news.ycombinator.com/item?id=48077924
The usual GC tradeoff is between memory and CPU performance. If you set the memory max high, the GC will run less often, you get less pause time.
So I do not understand why it's a surprise that minimizing the pause time requires more memory. Is it because there is no knob to set either the max pause time or the max memory ?
Because people generally do not understand memory management, and by people I mean majority of programmers, leading to dumb tales about performance of GC vs RAII/manual or even glorifying RC
When GC runs less often, doesn't that rather increase the amount of things needed to be cleaned up _when_ GC finally runs? So actually the GC time _at that point_ should be longer, not shorter, while in total summed up, it should be shorter. Running GC often means cleaning up less stuff for every GC run, so the GC time for each run should be shorter.
Do I have any misconceptions?
I think you're right, based on screwing around with Flash's GC a couple decades ago. (Iirc, you could only really control it with the debug player.)
Depends on the GC. For some the amount of work is related just to live objects.
I suspect 3.14.4 could have been tweaked slightly to address the issue without a revert - they could have prioritized checking the liveliness of objects sorted by size. I’m pretty sure that would fix the max RSS issue without needing a revert and the people unhappy with 3.14 could keep using 3.13 or switch to 3.14 and simply inject explicit calls to gc.gc().
Figuring out how to measure the size of an object can be tricky of course, but I suspect there’s all sorts of things you could try including figuring out how much memory got deallocated after you gc a cycle and attributing it to where the object got allocated as a heuristic to measure the mean allocation size.
> I suspect 3.14.4 could have been tweaked slightly to address the issue without a revert
I'm sure all the people that have been working on this for years would be interested in your small tweak, that they didn't think of, and would happily accept the PR!
Maybe they could have included an option to switch between GC implementations, like Java had done before.
Maybe in all those years they could have thought of that.
They did think of that, and decided it's not worth the maintenance burden.
https://discuss.python.org/t/reverting-the-incremental-gc-in...
The options are
a) do work to reduce issues as they come up b) appease the vocal complaints
A takes work, guts, and risk. Option b was chosen with the GC work basically saddled with so much process it’s never going to change. Python has a very storied history of being very committee driven design so the committee did the committee thing.
Anyone who’s worked in incident response will tell you why you’re wrong.
Tweaking the GC while the system was functionally broken is the worst time to do it. Correct incident response is revert first, figure out how to fix it later.
The difference being this is not a live system and thus incident response is very different. Applying best practices from incident response to development of a language is simply incorrect
You're simply incorrect here. The GC was in versions 3.14.0 to 3.14.4. See https://docs.python.org/3/whatsnew/3.14.html#whatsnew314-inc...
On what planet is the currently released version of any software "not a live system?"
Do you live on a planet where the Python language maintainers are deploying Python into your servers or managing them? Do you live on a planet where a new version of Python being released gets instantly and automatically deployed into your systems without testing and validation?
You are responsible for that, not them. And if Python 3.13 is fine for you and you report a performance regression for 3.14, you can still stay on 3.13. And as you say, it was introduced in a new release. What happens when the other side goes and says “3.14.5 regressed on the GC pause times and my p95 web server latencies went up. Please revert”? At least one side can make the case “performance was changed on a major release of Python boundary” while the other is changing the performance on a minor release boundary. It’s an arbitrary decision that speaks to the politics of the organization and less about a well reasoned technical plan.
Your argument is, frankly, idiotic. If a version of Windows, or any deployed software, has a performance regression, do you consider it “not a live product” because you didn’t personally install it yet?
I really don’t have words. When people bemoan the state of software engineering, your comment here is exactly what they’re talking about.
3.14.5 has a serious performance regression - GC pause times have increased significantly since the entire 3.14 series. This is the problem - you’re arbitrarily putting max RSS of certain workloads over the p95 latency of others. It’s arbitrary and why the worst kind of software engineering that inhibits software progress for the sake of nothing changing.
As for Windows, I think you need a better example. OSes frequently change their performance profile on certain workloads and use more memory. Terrible example.
Also please cool it with the personal insults. They’re not productive and shows you’re trying to win the argument through force and emotion instead of reason.
Snarky comment aside, Python is definitely *not* a "live system". If you had worked with such system before you'd know the world of difference between a version release of "stable" software versus a live platform that cannot fail.
> If you had worked with such system before
You mean software that has to be deployed locally? Like the example I gave?
> you'd know the world of difference
It's actually worse. The longer you take to get a fixed version out there, the more people will install the buggy version. As distribution is more difficult than just merging a Github PR, that buggy version will live longer on live systems. And before you say "but it's on the developer/DevOps/sysadmin to test," I point you to the countless CVEs where this didn't happen.
Knowing this is the situation, it's unconscionable to leave a faulty build on live for longer than necessary, when you can rollback the change with limited risk.
I do find the BDFL approach much better for language design. You might disagree with the direction of the language, but there is usually a "philosophy" or "taste" driven by one person that tends to be consistent over time.
In fact, I think Guido himself resigned due to the experience he had trying to get a PEP through the committee.
> In fact, I think Guido himself resigned due to the experience he had trying to get a PEP through the committee.
If you're referring to the steering council, that group was created in response to Guido stepping down.
He stepped down partly in response to the changing nature of online discussions around changes to the language. He just didn't want to be at the center of every polarizing discussion anymore. I think he also recognized that the transition needed to happen at some point, and that was as good a time as any.
Instead of "Reference counting primer" I would like to see a primer on how exactly such a huge change can go into Python without formal PIP process.
Because it's an implementation detail, not a change to the language itself. Similarly, when they re-implemented the dict type to preserve insert order, they also introduced it without a pep, because it was a side-effect of an implementation detail. Only later they decided people are so likely to depend on this, that they formalized it through a PEP.
Do people use python for new projects apart from ML stuff which hasn't moved to all-native yet?
My experience with Python is a really bad one for professional work: it's chaotic and slow, and has by far the worst versioning and packaging story of any mainstream language, yet its proponents keep praising it in denial.
I guess Python is an ok target for agentic coding, but my god do look Claude's commit messages pretentious, with code bases quickly heading into absolute unmaintainability. At least it had found gross JS injection vectors in a Django app that really shouldn't have made it through a code review, architecture level as they were, but oh well. A mature Django app is also not a nice dev experience IMO, with tons of implicit behavior all over the place encoded in a mix of magic filenames, database naming conventions, and URL routing quickly descending into regexp hacks.
> My experience with Python is a really bad one for professional work: it's chaotic and slow, and has by far the worst versioning and packaging story of any mainstream language, yet its proponents keep praising it in denial.
Some people just don't have the experience you do, "its proponent keep praising it in denial", can we have a better level of debate, come on now.
It's the classic worse is better.
The slowest of all dynamic scripting languages. Breaking ABI's and API's left and right all the time. Not able to implement basic performance optims. Their infrastructure (pip) getting worse and worse, getting everyone to install private venv's for every app, leading to missing security updates, because updates just break everything.
People just love trouble.
> Their infrastructure (pip) getting worse and worse
Hi, I'm a pip maintainer, can you please report any issue you think is happening in recent versions of pip: https://github.com/pypa/pip/
I particularly work on performance and stability and think we've been making big strides over the last two years
> getting everyone to install private venv's for every app, leading to missing security updates, because updates just break everything.
venv's stop your OS tooling from breaking, Linux distro maintainers pushed Python packaging to not allow installing into the system packages by default, and they weren't wrong.
All these other problems are solved with proper use of a lock file (which are now standardized, and you can generate and install from them in the latest version of pip), and/or use a project tool (uv, poetry, etc.).
Yeah I still use Python. I've been using it for a long time, I can get stuff done quickly with it, but I feel the same way you do to a big extent. Not sure what to use instead. I hate anything having to do with Javascript even though some parts of the JS world beat Python hollow (it's the other parts that are even worse than Python). Golang? Rust? Both too low level. I do use C++ (also low level) when I need something to run fast, but it's not the first stop. Erlang/Elixir? I like Erlang (haven't used Elixir) but it's too small a world and I'd want something with a serious type system if I'm gonna change languages. Haskell? Too much headache to do even simple things, such as logging. Scala? The bureaucracy of Java with the headaches of Haskell. OCaml? Maybe underrated and I should look into it more, but again it seems like Haskell's poorer cousin. I'm sure I'm overlooking some good ones though.
I'm split on Django--it's ok but I don't love it.
I don't think it's chaotic. I won't deny it's somewhat slow however usually anything performance sensitive gets shoved in a native code extension anyway.
As for packaging, I haven't had any problems with poetry or uv. The only time I ever had issues was with Windows in corporate environments where wheels were unavailable and it was also basically impossible to get the right toolchain installed for native code. However, not being able to install a compiler is not really a Python problem
Claude Code has a setting to change the git template so it doesn't attribute itself or you can also commit manually.
Half or more of the scientific research community live and breathe Python. Granted, it's Python 3.12, as 3.13 broke most of the C API, and everything COBOL and Fortran just about ground to a halt. But new projects are spun up constantly.
3.13 broke most of the C API
3.14 broke GC
I guess these kinds of priorities are exactly why Python is not my favorite programming language and why you have tens of Python versions installed on any machine. Not to talk about the Python 2 -> 3 drama that was also about fetishising syntax and pureness over pragmatism, installed base, and respect for existing code.
What happened in 3.13? Somehow I missed that. 2->3 was already a jump the shark incident though.
> I removed around 272 private functions and 15 private variables from the public C API (compared to Python 3.12 API).
[0] https://discuss.python.org/t/c-api-my-plan-to-clarify-privat...
Thanks, what madness. CPython wasn't abandoned in favor of PyPy at the 2 to 3 transition precisely because they wanted to keep the C extensions working. So what do they do next? Break the C extensions. Genius!
Python is the new Matlab and Mathematica combined.
Not anywhere near Mathematica, but a good replacement for Matlab. From a daily user of all those.
I forget who said it, but Python isn't the best at anything but it's decent to good at nearly everything, and that's why it's become so popular.
I do a lot of what I need symbolically in SymPy for dynamics analysis. Past that, I can't speak for it. At University I used Mathematica, but I just don't need all it can do at this point, so once again Python has proven to be "good enough." Matlab will be a similar story (e.g., I've never seen a good alternative to Simulink in Python).
But for everything else outside very specific domain tasks? Mathematica and Matlab are terrible for a lot of reasons. So I'll go out of my way to stay within the Python ecosystem, though I'm not afraid to pull out the specialty tools when I just can't make Python do the task near as well and/or nearly as quickly.
You are right in a way, but don't completely dismiss SymPy. Though I can see why you would never try it properly if you have a Mathematica license.
> apart from ML stuff
More and more applications need to use ML these days. So Python use will only grow.
I find the cult of python is hard to shift from some people. They just can't see it.
I see in the front page Pyodide 314.0 and now also Python 3.14. Is it a coincidence or is there some meaning to these "pi versions" in Python?
In Pyodide's new versioning scheme, the major version is the concatenated major and minor versions of the corresponding Python release. Pyodide 314 is based on Python 3.14 (which is just the fifteenth minor version of Python 3, counting from zero, and just happens to match the common approximation of pi).
Anthony Sottile had a video on the reversion over a month ago: https://www.youtube.com/watch?v=tQ3hnQiJ0YM
We definitely noticed behavioral differences in 3.14 regarding gc which could show up in particular test suites we have that are purposely ensuring all objects of a certain type were collected after a gc.collect() run. Between this and other issues (changes to the runtime API for typing, the first decently runnable version of free-threading, kind of a longer time for some C-based dependencies to catch up), the transition for my projects (SQLAlchemy) to 3.14 was generally more bumpy than that of say 3.12 or 3.13. will be interesting to see if 3.14.5 allows us to relax some changes we had to make to the test suite.
There was an issue recently with synapse, tbe matrix server implementation, where ram usage would grow until OOM.
The solution was to upgrade Python. But I won't, because that was the problem in the first place, here, apparently.
Oddly if I ran the whole thing under memray with a different allocator, no issue. I say oddly but it isn't.
So I guess my matrix server is broken until I rehome it on a new server with a fresh python instead of 3.10.8.
Just run it under uv :)
[flagged]
[flagged]
[dead]
[flagged]
but I aways use Python to analysis my medical data.
> Python 3.14.0 introduced a new incremental garbage collector. But reports of higher memory usage caused the Python team to revert the garbage collector changes in 3.14.5.
If they didn't have very good objective reasons the new GC is better, they never should have shipped it. If they do, they should not have reverted the change.
It's better in some ways (order-of-magnitude reductions in pause times were cited) but worse in other ways (higher peak memory usage). That the higher peak memory usage was catastrophic for some users only became apparent through post-release feedback.
They should have shipped it as an addon GC, not enabled by default. One could have turned it on with a command line switch or an env var, just like the Ruby JIT.
Really? You've never reverted a positive change because it contained a regression only discovered after release?
It's this sort of stuff that leaves me scratching my head why people like Python so much. I hear them say they prefer the syntax and personally I feel like that's such a small part of the holistic experience of working with any particular language. It's one of the reasons why I gave up on C++ years ago for .NET, the whole system of tooling in .NET has never left me feeling like I was pigeonholed into doing things in stupid, self-flagelating ways. Why should I use a language like C++ that doesn't provide a standard set of package management and build tools? Why should I use a language like Python that feels like it's being designed by amateurs?
I felt like the tooling in Racket, CLisp, and Java were similarly pragmatic and not either religiously devoted to some concept of "backwards compatibility" that I seriously doubt most people actually need, or "ease of use" that actually proves itself to be easy when you consider the not-happy-path of the beginner tutorials. Racket, I didn't continue just because the library ecosystem isn't mature enough to keep up with the latest in databases and other 3rd party services. Java I quit largely because of Oracle and some 2010s problems with stagnation. CLisp mostly because it was too hard to socialize. But never because I thought the core language and tooling were holding me back.
You are right the syntax is a small part of it, but it is more important than you say in this case because Python syntax is one of the things that makes it very readable.
Even if you dislike the direction Python is going in, a lot of what attracted people to Python in the first place is still there. The readability, the large standard library, the huge ecosystem. There are libraries and frameworks for everything: numerical stuff, web development, GUIs etc. Its actually a nice language in itself, just going in the wrong direction now.
If you look at it historically it was really good comparatively. If you compare it to the alternatives available 20 years ago it looks pretty good.
When people say they prefer 'the syntax', I think they usually mean a bit more than just that: at least a fair bit of this is semantics. Python provides a lot of features out of the box, and if you work superficially along the happy path, it is very easy to understand how these work and read code using them.
Take list comprehensions for example. It is mostly syntax: you can do virtually all list comprehensions with just a map and filter function. But the way that it is integrated and presents the code, makes is vastly easier to follow for most developers, which tilts the balancer in favor of doing away with loops and mutable state. Is it syntax that made them do so? Yes, maybe. But its the actual semantics that provide the value.
It's easy to start learning on, or prototype with, and then sometimes momentum just keeps it going. Also it may not really be the best at anything, but it's "pretty good" at just about everything. It's kind of like vanilla ice cream.
Packaging can be irritating although uv takes the sting out a bit.
You are right that outside of verbosity, once you get used to the syntax of a language, the value of one over the other kind of fades.
> Packaging can be irritating although uv takes the sting out a bit.
uv proves the OP’s point. Why couldn’t the core team and the core-adjacent PyPA make a tool as liked as uv, and why is the Python package manager uv written in Rust and not Python?
For the same reason GP posted and half the stdlib is written in C: Python is a language that is almost always good enough, but never really the best (and especially when it comes to performance of complex algorithms).
Because uv itself can fetch a Python distribution. If it's written in Python, it's quite a bit harder to distribute, assuming one of their goals is not to require an existing Python install.
> Why couldn’t the core team and the core-adjacent PyPA make a tool as liked as uv
Incredibly large backward-compatibility burdens [0], internal politics [1] and general institutional dysfunction (no footnote; if you're familiar then you need no explanation, and if you aren't then the less said the better). Nothing to do with Python as a language. Most of the important pieces to get uv-like performance are algorithmic choices, and most of the rest are available as built-in C code in the reference implementation [2].
(Edit: wait, I recognize your username. You should definitely know these sorts of things.)
> why is the Python package manager uv written in Rust and not Python?
Because that's the language that Astral devs like, and because installing Python itself is considered in scope for uv so there would be an intractable bootstrapping issue.
[0]: In particular, the entire model of `setup.py` defining metadata is certifiably insane, especially when you consider the projects that expect to feed that code to Setuptools at build time in order to figure out what version of Setuptools is needed at build time. But this legacy approach is seen as something that absolutely must be guaranteed to work for well beyond even now; even attempts to remove long-deprecated, minor aspects of that functionality end up breaking major projects, including ones that didn't even require a build step in the first place [3].
[1]: Most obviously, GvR not wanting to have anything to do with it when initially approached by the SciPy people in IIRC 2011, leading to the creation of Conda). But a lot of other things, too. The backwards-compatibility issues synergize with this; consider for example the architectural dumpster fire of Setuptools, and the timeline of distutils removal from the standard library.
[2]: See e.g. my analysis in https://zahlman.github.io/posts/oxidation/ .
[3]: See e.g. my LWN article https://lwn.net/Articles/1020576/ .
Any claims that Python has a huge backwards compat mission go right out the window when you consider Python 3. 3 was a perfect chance to fix all of the major problems with Python, problems other languages have solved so there isn't even a need to invent things from scratch. They didn't and that's why the community is still split on adoption.
I don’t think there is still a Python 2 split, the lack of security updates being a concern
I have no idea what you're talking about. 3.x objectively did fix the major problems and was not particularly inventive in its approach. The fact that they didn't fix more things all at once — and the fact that they still received massive complaints about supposedly fixing too much — is the origin of that backwards compatibility mission. Actually talking to the devs for any significant length of time makes it clear how much lasting trauma was caused by the change, and how much that cemented pro-backwards-compatibility views. And the community has not been remotely "split on adoption" for years; hardly anyone publishes packages advertised as 2.x compatible any more (e.g. urllib3 gave up almost two years ago). But to the extent that there have been any holdouts at all, it's been people who want ancient systems to work, not people who think that not enough changed to merit upgrading.
Python 3 got very slow update and poor acceptance precisely because it DIDN'T fix major problems, it only tweaked around the edges of minor ones. So people stayed with Python 2 as long as possible. Here's a post from 2014 that I bookmarked and it explains things a decade+ later:
https://news.ycombinator.com/item?id=7802575
From the link: "You know why I'm not running python 3? Because it doesn't solve a single problem I have. It doesn't solve anyone's problems. It solves imaginary problems, while creating real problems."
C++ has vcpkg, conan, cmake and ninja nowadays.
They are as standard as arguing about Ant, Maven, Gradle in Java, npm, pnpm, yarn in node, and so on.
However I fully agree with the gist of your comment, basically Python is the new BASIC.
However at least BASIC was compiled, with exception of the 8 bit home micros.
> Racket, CLisp
Syntax really does matter more than you give it credit for. Were that not the case, I'd expect one Lisp or Scheme dialect or other to take Python's place. Outside of that counterfactual, Python's competition was stuff like Ruby, and it turned out that network effects were also pretty important.
Python's main competition was Perl. Ruby was later, I think.
> It's this sort of stuff that leaves me scratching my head why people like Python so much
Because of the libraries, not necessarily the language, which is also quite straightforward. For example we found a niche library that speaks the ISO-TP protocol in Python, which allows us to communicate with vehicle ECUs. That's why people also use C++, even tough I quite doubt it's because they like the language. Add to that that it's also heavily used in embedded programming. Yes, you could call a C/C++ library from another language, depending how well the language can do that.
I prefer Ruby, but Python probably has just about everything one would need. It's also great for data processing. We hardly have anything better than pandas, polars, numpy, scipy in other languages and that:s without even mentioning ML tooling.
Python is mostly about the “batteries included” standard library and what’s becoming nearly standard third party libs, being able to play around in the REPL,
The standard library is full of dead batteries. If the stdlib is so good, why does everyone install requests instead of using the stdlib http client? And why requests or something like it hasn't been adopted into stdlib after so many years of stability?
Parts of requests has been adopted into stdlib: https://docs.python.org/3/library/urllib.request.html
People mostly defer to requests because they do not track language development closely and because we are creatures of habit.
I try to avoid non-stdlib packages when stdlib will do a good job, but I received negative feedback from people who aren't aware of the updates and couldn't foresee supply-chain attacks.
The current standard library urllib is a refactoring of previous attempts from the 2.x standard library, and urllib.request is just a sub-package. It does not represent adoption of requests; requests builds on urllib3, which was created to fill in gaps in what the standard library provided, and named like that because the 2.x standard library had both a `urllib` and a `urllib2` as they struggled to figure it out.
For a long time, urllib had everything deprecated except for the parsing code which remained relevant as the upstream RFCs have not changed IIRC.
Urllib2 is now also gone and mostly replaced with urllib.request.
It should cover 99% of the use-cases one would use requests for — I am not sure how and why it matters that it is a subpackage and not a top-level package?
This is just a natural evolution of a widely used language where you have to be careful with backwards compatibility.
You are picking one of the weak points of the standard library and an unusually popular replacement (and AFAIK it is built on the standard library). I cannot think of many others that are widely used. Maybe lxml ?
A Python codebase might well use requests, but it will almost always also heavily use the standard library.
Because the typical Python programmer does not appreciate the advantages of a slightly rusty stdlib compared to reaching for the bedlam that is PyPI.
> “batteries included” standard library and what’s becoming nearly standard third party libs
Historically, the standard library made sense. And we're talking about a history that stretches back to before Internet connections were ubiquitous, to say nothing of connection speed.
Now the standard library is full of things that they refuse to remove because it would supposedly be too disruptive, but which they would never think of adding today if they weren't already there.