What prevents you from using an old Python version?
My current solution is a docker container which includes python 2.7 and a downloaded copy of every package I use.
I think the fact that it's not on the distributions is a major factor here.
With no python version manager (I don’t even know any off the top of my head).
Also virtualenvs only get you so far, I’ve come back to many projects on my machine with broken virtualenvs, I guess due to some dynamically linked dependency of python that my system no longer has.
:(
Try a tool called `pyenv`. It's pretty great. I pair it with the package manager called `poetry`.
Edit: Somebody's going to respond with the XKCD aren't they? I know about the XKCD and I nevertheless have high hopes for `uv`.
https://github.com/asdf-vm/asdf
And here's a list of everything it supports: https://github.com/asdf-vm/asdf-plugins/tree/master/plugins
Beside, "figure out which ones work" is a solved issue with a package manager such as poetry.
I don't especially like language-specific package downloaders either but that's not a Python-only problem, and there are tradeoffs to pushing the work downstream into more stable systems.
For such a long lived language to have this much immaturity is worrying. I guess the side affect of such popularity later in life.
I'm one of the people who was unkeen to move to Py3. My reason was mostly the numerous and totally unnecessary minor syntax changes (print -> function, map and filter becoming lazy, str/unicode etc) with no major benefits in the upgrade for my use case (data science), other than compatibility. Some of the new syntax was neither bad or good (what's so wrong with print being a statement? Add a printfn function if you really want one), some were IMHO outright bad (map and filter becoming lazy, reduce being kicked out to a module), str->unicode was maybe the only good one, but even that is controversial. The deliberate neutering of `bytes` was unnecessary too. Python 3 brought various implementation improvements and nice new syntax, which could have been implemented in a Python 2 syntax too (dict and set comprehensions for example)
So I saw no reason why Python 3 couldn't in fact be syntactically compatible with 2, and saw the whole thing as a bit of an upgrade circus: wanna keep using the language? Make these arbitrary changes because someone thought print ought to be a function.
You could argue it was the same disregard for stability as the now many versions of Python 3.
From the PEP[0]:
print is the only application-level functionality that has a statement dedicated to it. Within Python’s world, syntax is generally used as a last resort, when something can’t be done without help from the compiler. Print doesn’t qualify for such an exception.
At some point in application development one quite often feels the need to replace print output by something more sophisticated, like logging calls or calls into some other I/O library. With a print() function, this is a straightforward string replacement, today it is a mess adding all those parentheses and possibly converting >>stream style syntax.
Having special syntax for print puts up a much larger barrier for evolution, e.g. a hypothetical new printf() function is not too far fetched when it will coexist with a print() function.
There’s no easy way to convert print statements into another call if one needs a different separator, not spaces, or none at all. Also, there’s no easy way at all to conveniently print objects with some other separator than a space.
If print() is a function, it would be much easier to replace it within one module (just def print(*args):...) or even throughout a program (e.g. by putting a different function in __builtin__.print). As it is, one can do this by writing a class with a write() method and assigning that to sys.stdout – that’s not bad, but definitely a much larger conceptual leap, and it works at a different level than print.
[0] https://peps.python.org/pep-3105But breaking one of the most commonly used statements for what is essentially aesthetics? No thanks. Introduce a function that does the same if you like.
That's precisely my point, this syntax change (and many others) was entirely unnecessary, put people off upgrading, then got them told off for being dinosauric luddites.
Frankly, it's not even that consistent. Is `del dict[key]` necessary when you can call `dict.pop`?
Either way, these would be fine discussions to have, but not when you consider the people upgrading thei codebases.
Reason for Python 4 detected!
I would never use Python 2 now, but I do understand why some people would choose 2 back when 3 was new (and even slower than 2!).
Would you not use Pathlib?
Rust has a similar thing with OsStr. In my opinion a clear type based separation between different kinds of strings (Text, data, os path, ...) is just required to write robust softwsre
I use python3 now by default, as it has fstrings, and probably some iteration things that I now rely on, and is faster for a lot of things.
But for the longest time the only difference that I bumped into was that print isnt a keyword anymore, but assert still is.
But it's good that it's Unicode.
(I think it was 3.3 when they compromised, maybe 3.4?)
Mature languages don’t tend to break working code. That was true when the quote was pronounced and that’s still true today.
Python is fairly unique in its propensity to be an unstable target. I personally can only think of the JS ecosystem has being worse but even then that’s mostly a library thing as the VM will run even the oldest JS code you can find. I wish the same could be said of Python.
From Python being brittle?
It’s one of the rare language which deprecates and removes API between minor versions. They have to provide migration guides with every release.
I'm also the type of person that doesn't do version-pinning as I think the concept is an anti-pattern that came from the JS world as a way to manage the chaos borne-about by the constant API changes, thousands of tiny libraries, and library dependency updates that it circularly-co-caused.
Python changes because of three reasons: Addressing bugs and insecure patterns; support for new usage patterns in the community; updates for compatibility with newer devices and systems.
The first one is a given. The second and third are basically "the world is evolving, with or without you". Even if you built a VM on your perfect machine, with your perfect python and perfect libraries and froze everything for 10 years, the moment you connected it to the internet you'd be faced with "Ah, my perfect version does not support this new thingamajig being used on the web".
Freezing everything in time is just archiving.
Python is a couple abstraction layers above that, it's not supposed to even be directly exposed to things that vary frequently between devices. That's a job of the OS, the C compiler, and the libraries (most of which just link to C ones anyway).
None of this explains why python has the need to drop modules for the standard library.
They claim "nobody is maintaining them"… but they are well funded and can easily afford someone to maintain them.
I think at the core they don't care about backwards compatibility, but instead of doing it all at once like with python2/3 are now doing it little by little, creating a python4 without calling it so.
That's the unfortunate modern trend. The web folks that move fast and break things love living on the bleeding edge, and create strong pressure for everyone to keep up, and that the answer to library compatibility is "wait until someone complains, fix the direct reason, cut a new release, and let the dependents fix their own code".
You still have to find someone who both wants and can maintain them. That's not always a given.
And also, why? If I donate to the PSF, do I really want my money to go into the maintenance of ... checks notes ... MacOS 9 path manipulation functions (https://docs.python.org/it/3.7/library/macpath.html)?
Just because you're well-funded doesn't mean you get to spend money on useless things. And most of the python community would consider this useless. Nobody even made a pypi copy of it.
I don't think Python is perfect, I don't mind changes. But I do mind backward incompatible changes a lot.
Python is my main language and backward compatibility is far more important to me than performance.
Almost everything I do spends most of its time waiting for IO, or in a C library, or another process, or performance is unimportant. That is why Python is my main language.
I think it is possible that Python's popularity with people doing numerical stuff might end up making it worse for the rest of us.
I've been using Python since long before it became the go-to choice for numerics inside and outside academia, so let me tell you: It was even worse back then. The transition from 2.7 to 3.0 was both regarding the fundamental idea and the implementation the worst thing I have ever seen happen in any major language. This could (maybe should) have been a language killer. They should have just branched it out as something completely new. Van Rossum is totally right in saying that he never wants a Python 4 for that reason, so it seems at least he learned a little bit since then.
A big attraction of Python is that it can do everything. Very useful if you need more than one of the above in a single project.
On the other hand I do feel that Python has been bad for my personal development because I can always find a Python library for any and everything it has reduced my motivation to learn other languages properly (i.e. actually using them for real work - I have learned a few in theory). I have been stuck with the same main (to the point of dominance!) language for far too long.
Yes, 2 to 3 was pretty painful, although it was not too bad for me because I was mostly able to delay moving until i was sure all the libraries I used had made the transition.
As systems started shipping Python 3, the convention among most of them became to leave `python` as a Python 2 interpreter and then introduce `python3` as a Python 3 interpreter. As they then stopped shipping Python 2, they generally just removed /usr/bin/python, so the only Python on the system was /usr/bin/python3.
In my own scripts to build Google stuff, I always had to make a folder with a single script called `python` which would contain just `exec python3 "$@"`, and then prepend that directory to the `PATH` when invoking Google's tools.
Google eventually did update their stuff to work on systems where the only Python is `python3`, but man this transition was rough. As I understand it, Google had good reason to do it their way at the time too; there was simply no consistency in how systems handled the 2 -> 3 switch. I suspect that this is due to a severe lack of guidance from the Python foundation.
Imagine if GNU released a new, highly backwards incompatible version of bash called Bash 6, and then some platforms kept /bin/bash as Bash 5 and introduced /bin/bash6, some systems replaced /bin/bash with Bash 6 and introduced /bin/bash5, and some systems removed /bin/bash entirely and /bin/bash6 was the only Bash on the system.
Python had the opportunity to be, and was, to some extent, just a standard part of a UNIX-like system, like bash. But now it's just another language where you need to care a lot about interpreter versions and how different distros package it differently and keeping code up to date to work with the latest Python and keeping Python up to date to work with the latest code.
This doesn't mean that Python is bad, but it would have been much more useful to me, and quite a few others, if it had stated a ubiquitous tool which is more like Bash and Perl.
Just because the BFDL doesn't increment the major version doesn't change the fact that myriad breaking changes arrive in Python 3 PEPs.
This is purely an optics hack. Python 3.0 is very different from Python 3.13. Had the frog not been boiled slowly, it might as well have been Python 4.
The people who could stop this churn will not. It's a full-employment ticket for them, chasing dot-release upgrades and educating us about changes that we couldn't live without but somehow did for decades.
It takes a big person to say when something is good enough despite its warts. Contrast the Python churn with Linux and git: never break user space.
Windows 11 is a thing.
I didn't say things can't change. I said don't play games with major version numbers to window dress optics.
Survivorship bias. Python just barely survived the transition, and you only still use it now because it did make it. Take a look at Perl 6 to see a major language that failed.
Dealing with Python after mostly taking a pause around time 3.0 was introduced, I was shocked at the mess. And unlike with Perl 6, which took quite a clean break even before it decided to rebrand, you ended up with situation where both were around semi-equally, and there were "fun" bugs introduced in Python 3 that caused explosive bugs that we couldn't figure out in beginning because things would always work on developer machines...
Does it by any chance a process started by multiprocessing? /s.
On a serious note, I feel like this is a valid usage and as someone who really like the no-gil approach I still would want python to handle the gil and no-gil flags in a better way. I don't know yet how this will manifest in real life and if keeping gil will be an option on the long run but it is a trade-off. There is no fundamental reason why python cannot have proper multithreading support.
It drives me _nuts_ when I find a simple library to do a small-ish thing that I don't want to write/maintain myself only to discover that it uses numpy or pandas because they're "fast".
I wrote some python programs that did multithreading, but they didn't work and I had to go elsewhere.
So... it is possible you won't find many people in your sample that disagree because the folks that went elsewhere... aren't part of the sample.
You don’t have to install the latest version if you don’t want to. If you use a version manager, you can keep using whatever version you want for many years.
i don't think it's too surprising that versions differ. there are good tools to manage the python version used -- i personally like pyenv.
As I said, a lot of the value I see in python is in its ubiquity. This disappears if you can't use the system python.
But if you value that ubiquity more than your sanity, I hope you find and fix any breakage yourself and not pester other devs for support.
+1
Most Python use case today is some what on the similar lines as Perl. Having a stable large install base. Availability of libraries, backwards compatibility, performance matter way more than more features at this point.
There is no new replacement language in sight, so Im guessing we will be using Python for long into the coming future.
I also hope Python had something on the lines similar to CPAN. We are decades into the journey, and Perl still shines like the Sun in this regard.
Part of me feels sad Perl 5 didn't go the way Python 3 did.
Especially considering how a major distro[1] that defaulted to Python 2.7 only just was dropped by many[2] - but not all, because some "heroes" jumped at the last moment to provide binary compatible support options
[1] CentOS 7
[2] Especially if you wanted to be in any case acceptable to sell to FedRAMP-requiring or similar clientele, but in Europe NIS 1 (already in force) and NIS2 (starts enforcement this year) ban software that is post end-of-support
What do you mean? I've been using python since 1.5 and it is more ubiquitous today than it has ever been at any other time in the past.
I remember Python around 2.2 becoming ubiquitous and "obvious" option as "better than perl and also certainly available". Python people would even trash talk other communities for not being able to "just download the libraries from distro repo" or needing specific versions whereas you at worst grabbed updated python for your distro.
(The following is a somewhat chronological rant)
Fast forward few years and me getting out of university which for various reasons was (apparently blissfully) Python free. In between we get through the "huge"transition from Ruby 1.8 to 1.9/2.0 (had to help professor update coursework even).
The 2->3 transition interrupted that, and I am suddenly facing that a) python3 actually got released b) despite several years, it's not even guaranteed default c) you now have to explicitly use python3 or python3 in shebangs because you don't know what version of python is default d) virtualenv wtf e) there's still new code being written depending on py2 f) the library situation can be a maze.
Since I mainly worked as "DevOps" person, not a python programmer, I get to deal with increasingly borked python deployments. Suddenly authors names in comments cause deployments to fail on servers but work on dev machines as well as mine. Took long to figure, the same code working when connecting over SSH vs not working when started by systemd shows it's python deciding encoding by locale and barfing on 8bit characters (including utf-8).
Virtualenv, increasingly necessary multiple python versions, all driving increasing replacement of python in admin/management tooling. Chef and Puppet (finally) laughing from their omnibus setups at ansible exploding depending on what python is default on target distro and people who pushed ansible confused because "it only uses SSH, there's no agent". Even more movement to Golang because of static binaries.
Virtualenv becomes the effective default, forget about installing packages through distro (subjective take, I know, this is a vibe I know it's still possible).
Python 2 goes EOL and out of support but it's still default on distros used by paying customers (this changes - but not fully - this year on June 30th... Thanks to government regulation - thanks Obama /s)
I now mostly see python deployed with not just batteries but the whole jungle included (Docker). If it's s good container it doesn't have a complete copy of development environment.
Increasing mess with packaging. Distros reducing python dependencies, system python increasingly seems mostly for use only by OS components. Python equivalents of rbenv/rvm increasingly suggested as "right tool". Package build items exploding because transitive rust deps.
Customers sometimes demanding OS installs without Python. Increasingly encountering distros with no python at all.
Python packaging still feels worse today than rubygems were a decade ago.
Finally increasingly suggesting to prospective projects that benefit/cost of python goes below 1.
I used to love python back in 2002-2006 timeframe. Rails making it so damn easy to handle some projects and finally starting to grow Lisp (thanks to a detour through Haskell due to XMonad) made me look away. Even "ML ecosystem" mostly gives me more reasons to rant against Python (Tensorflow packaging as PIP wheel makes me problems even when I am going to use Python.
So, yeah, lots of code in Python, ubiquitous python jobs. Retreat from "write your tool in python, it will be easy to distribute, every distro effectively preinstalls python unless it's some LFS or Slackware weirdo"
I get that for people for whom Python is their main language, all these changes make their lives better. But for me it kinda just gets in the way. Personally, I wish Python would continue to be maintained as is, but stop changing so much. Stop breaking my builds.