1. 37
  1. 27

    Damn. I remember when people where writing articles like this about Python 2.7. Time really does fly.

    1. 11

      Checked the comments for this exact sentiment. I want to say “but I just cut everything over from 2.x!”, but then I realize that was 4-5 years ago…

      1. 6

        The introduction of Python 3 was traumatic for the entire ecosystem. I still have to install packages like python-is-python3 [1] on some machines because otherwise, some things just don’t work. This was more than a decade of pain.

        [1] https://packages.ubuntu.com/jammy/python/python-is-python3

        1. 5

          I still have to make hacks in things like build scripts to accommodate for tools which “work” with python 3 but expect the shebang #!/usr/bin/env python to work. All of Google’s C++ stuff, for example, assumes python is python 3, which it just isn’t on most systems.

          Personally, I don’t care about any of the improvements in Python 3, they just made string handling a bit more annoying. But it’s impressive that the roll-out was so incredibly botched that it’s still causing major problems 15 years later.

      2. 20

        Luckily, Python 3 releases are fairly backwards compatible. …

        A symptom of a bigger problem

        The need to upgrade is not a one-time event, it’s an ongoing requirement: … If you’re still on Python 3.7, that is a symptom you are suffering from an organizational problem

        One could argue that the “bigger problem” here is actually that it’s not possible in-principle to write software in Python today (or for many popular platforms) that will definitely still work on a system with security patches five years from now.

        i.e. If you want to write software that is “finished”, as I often do as a person who wants to start the occasional new project and doesn’t have quadratic time to spend on maintenance, your options are very limited.

        1. 7

          Python sometimes deprecates and removes things even within a major release series, and of course some people dislike that, though I find it’s pretty minor myself.

          But I’d argue that it’s much more of a problem – speaking as a maintainer of open-source code – that some people think they can just call their software “finished”.

          What you’re actually doing in that case is demanding that I (and every other maintainer of something your “finished” software depends on) promise to provide bug fix and security support to you and your users, from now until the heat death of the universe, and also never do feature releases again because your users might be tempted into upgrading and then your software might not be “finished” anymore.

          And… I won’t even quote you a price on that; it’s a complete non-starter. If you want maintenance of your dependencies past the period the upstream provides (and in the case of Python it’s five years for each minor/feature release), you can do it yourself or find someone willing and pay them whatever they charge for the service.

          1. 14

            Of course I’m not expecting that a giant list of dependencies will be perpetually updated for me. But if I write a simple utility with no dependencies other than the language runtime, then yeah, that should be finished. I shouldn’t need to add it to an ever-growing list of “things I maintain now until I die”, and neither should you.

            You don’t owe me any particular kind of maintenance, and I don’t owe you any particular kind of maintenance. This is all gratis; we’re all doing it for fun or because we care about it or because we think it will get us a job.

            For what it’s worth, Rust has solved this problem, as far as I’m concerned, with Rust Editions. It’s not impossible; it doesn’t require an ongoing sisyphean effort performed for free.

            1. 3

              But if I write a simple utility with no dependencies other than the language runtime, then yeah, that should be finished

              Python has a clear support policy: feature releases get five years. If you want to declare your software “finished”, then in at most five years it will no longer be receiving bugfix and security support of the platform it runs on.

              Meanwhile I’m not super optimistic about Rust having solved this “problem”. The language is still extremely young and they’re accumulating a lot of “we promise to keep this working for you forever” stuff that I think is not sustainable over the kinds of time horizons the “finished software” people will want.

              (my own stance is that the only way software can be “finished” is when it’s no longer used by anyone, anywhere, and never will be again)

              1. 4

                the only way software can be “finished” is when it’s no longer used by anyone, anywhere, and never will be again

                This is trivially false if your software is running in an environment where it doesn’t have to care about security. I can run just about any unmodified video game ROM from the 80s on my laptop using an emulator. There’s no inherent difference between a video game emulator and a language implementation - the difference is that one of them is “retrocomputing” and the other is “general-purpose programming”. Rust editions are essentially cutting “retrocomputing releases”. Python could do the same, or someone else could do so (and some have built 2.7 forks, to much gnashing of teeth)

                1. 9

                  Note that virtually every C compiler can still compile code from the nineties (that’s thirty years ago) using options like --std=c89. The same is true for Common Lisp, although that’s not an evolving standard like C is. Fortran compilers can compile code from the seventies…

                  But for modern languages it’s sort of acceptable to not have backwards compatibility. Of course, backwards compatibility also has a flip side in that it means every bad decision must be kept around forever (although it can be deprecated or even dropped in newer “modes” of course).

                  1. 3

                    The aggressive breakage is makework. My tolerance for that varies greatly based on the season I’m in. But, if I’ve marked something finished and it must be updated to support Critical Business Functions, that’s where support contracts come in.

                    (I suppose I’m not quite compatible with open source still.)

                  2. 4

                    You can run unmodified Python code on your laptop too. You just have to run it in a VM that has a compatible Python interpreter for it to run. That is essentially the same thing you are doing when you run your 80’s ROMs on an emulator. You are handling the maintenance of getting that ROM to work by changing the environment around it to suit it, the same thing you’d have to do with the old Python code.

                    1. 3

                      In the same vein as another reply: you’re relying on the emulator being maintained, in the same way you’re relying on a specific version of the Python interpreter to be maintained. You’re also relying on the games not having any show-stopping bugs in them, because the original vendor is long past the point of fixing them.

                      So no matter how you choose to phrase it, yes, you really are relying on others to do long-term maintenance on your behalf as part of your ’finished” software.

              2. 1

                Trying to think here if your problem needs to be solved at the language level, or at the packaging level. Would you be happy if there was a tool that could package your code + dependencies + any version of the python interpreter into a binary? Then, as long as the code, the packaging tool, and the pinned version of your dependencies were available, anyone could package it from source.

                This only moves the problem, of course, because such a tool doesn’t exist. But other languages have similar problems: I doubt you can run ruby or php from 10 years ago in the latest version with zero hiccups.

                1. 1

                  This only moves the problem, of course, because such a tool doesn’t exist

                  You can do this easily without any involvement of the language or the packaging level with any virtualization/containerization tool.

                  There are also quite a few tools that do more like you suggest of producing a “binary installer” type distribution – off the top of my head: PyOxidizer, PyInstaller, and py2exe are all alternatives in that space, but I know there are some others, too.

                2. 1

                  This is why I usually target apps whatever Python interpreter current Ubuntu LTS ships with, so it will be working for a long time for a lot of people.

                  1. 1

                    The solution is to ship your own python interpreter with your application or to achieve the same effect, containerize it.

                  2. 7

                    I feel like Python is the only language where I see posts like this. I think a big reason is that most Python code does not use any of the newer features anyway, so there’s no carrot to upgrade, only stick.

                    1. 5

                      Well, the latest release bought some very nice performance improvements: https://docs.python.org/3/whatsnew/3.11.html#summary-release-highlights.

                      Also, Node and Ruby (that are the other “big” interpret languages used nowadays) also have big releases breaking things and nobody seems to care that much. Not sure why the issue is only with Python, maybe because it is used in more contexts where people are not “engineers” (e.g.: scientific communities).

                      1. 4

                        I think a big reason is that most Python code does not use any of the newer features anyway

                        Speaking as someone who’s been involved in a very popular Python package (Django): it’s more complex than that.

                        Python does yearly feature releases and a five-year support cycle for each one. So, suppose that a useful bit of new syntax gets introduced in Python 3.12. It’s not available in, and in fact is a syntax error in, Python 3.10, 3.9, 3.8, etc.

                        Which means that if you’re a package maintainer who wants to stay compatible with the full range of upstream supported Python versions, you are always five years behind the state of the art and people take jabs at you on internet forums for not adopting new features. But if you break compatibility early to adopt the feature, people take jabs at you on internet forums for forcing unnecessary “make work” upgrades on everyone.

                        Python 3.7’s end of support will allow big packages to finally start adopting Python 3.8 features: audit hooks, the walrus operator, positional-only parameters. But even newer things like pattern matching – a huge feature in Python 3.10 – won’t be generally usable by big packages until sometime in late 2025 due to having to wait until Python 3.9 falls out of support.

                      2. 1

                        I thought that the title was about Python 2.7 :)