Core Devs Say A Fond But Firm Farewell To Python 2

Saying that it was finally time for the community to bid a “fond but firm farewell to Python 2”, core developer Benjamin Peterson marked the release of Python 2.7.18 on April 20th; officially ending support for the 2.x branch of the popular programming language. It was hardly a snap decision. Python 3.0 was released all the way back in December 2008, and it was never a secret that the newer branch was not only incompatible with the earlier version, but that it would eventually superseded it to become the standard.

But migrating the incredible amount of Python code in the wild over to the latest and greatest was easier said than done. Millions upon millions of lines of code used in everything from Linux distributions to virtually every major web service needed to be reviewed and migrated over to Python 3. In many cases the changes were relatively minor, but when code is being used in mission critical applications, even the smallest of changes are often avoided unless it’s absolutely necessary. The voluntary migration took far longer than expected, and the end-of-life (EOL) for Python 2 was pushed back by years to accommodate developers who hadn’t made the necessary changes yet.

Given the somewhat fluid nature of the Python 2 EOL date, it seems fitting that this last final release would come several months after the “official” January 2020 deadline. The intention was for it to coincide with PyCon 2020, but just like so many of the events planned for the first half of the year, the in-person conference had to be canceled in favor of a virtual one due to the COVID-19 epidemic. That might have stymied the celebration somewhat, but the release of Python 2.7.18 will still be looked on as a special moment for everyone involved.

Too Big to Fail

If everything had gone according to plan, this milestone would have been celebrated sometime in 2015 as that was the sunset date originally announced back in 2008. But as the EOL date got closer, it became clear that the community simply wasn’t ready to make the switch. The problem was complicated by the nature of Python development, which generally involves pulling in a number of upstream libraries. Even if individual developers were ready and able to move their code over to the newest release of Python, the libraries their project relied on might not be so agile. Until large and popular libraries made the switch, end-users were stuck in limbo.

Python is now the second most popular language on GitHub

For the hobby Python user, getting your code ready for Python 3 was often as simple as making sure your print() functions had the proper syntax. But migrating a huge library was another story.

There were many changes to the more esoteric functions of the language that needed to be taken into account, which meant updating would eat up a large chunk of development time; not something many open source libraries have an abundance of to begin with. Without a clear advantage to moving their libraries over to Python 3, many developers simply decided not to.

In a perfect world, it wouldn’t matter if people wanted to stick to the older version they were more comfortable with. But we don’t live in that world, and with so many websites and online services relying on Python 2, the fact that developers weren’t updating became a liability. Those in charge of large Python projects were often left with an unenviable decision: either live with the known bugs and security issues, or make the leap to Python 3 which will break backwards compatibility and require refactoring large swaths of code.

Seeing the magnitude of the situation, the Python developers introduced PEP 466 — Network Security Enhancements for Python 2.7.x in 2014. This update specifically addressed the aging implementation of SSL in the older Python series which was seen as a serious security risk for projects that were unable or unwilling to upgrade to the 3.x branch. It was a deviation from how feature updates were normally handled in the Python development process, but it was deemed necessary given the circumstances.

As Peterson noted in the Python 2.7.18 announcement: “Traditionally, these features would never have been added to a branch in maintenance mode, but exceptions were made to keep Python 2 users secure.”

The Future of Python 2

Despite having more than a decade to prepare, it would be naive to think that every project has migrated over to Python 3. The largest and best known libraries have switched over at this point, or are at least are in the process of doing so, but there’s no question that there’s plenty of Python 2 code still running out there. We’ve recently been reminded of how many critical systems are still running COBOL, an archaic language now over 60 years old. It seems inevitable that pockets of Python 2 code will remain in operation for years or even decades to come, simply because nobody wants to go in and rewrite something that’s already working.

Will your banking information or other critical data pass through some Python 2 code today? It’s certainly possible, perhaps even likely. It probably won’t even be Python 2.7.18, either. That’s not necessarily a problem right now, but any bugs and security vulnerabilities discovered from this day forward won’t be fixed. They might not even get reported through official channels. Anyone running an unsupported version of Python shouldn’t expect much help coming their way when the next major vulnerability is discovered.

So in the future will we be reading about companies scrambling to find Python 2 developers that know how to fix an entrenched piece of software that hasn’t been updated in decades? Luckily, the two versions of Python are similar enough that updating the code is generally more a matter of time than difficulty. We should have developers who are capable of doing the job for the foreseeable future, but it might not come cheap.

32 thoughts on “Core Devs Say A Fond But Firm Farewell To Python 2

  1. I keep running into open source projects that need python2 to run their scripts. I know this because they’ll have #!/usr/bin/python but my system default is python3. I end up having to hack in old python for these scripts.

    I usually write my own scripts in sh or awk because it seems to break less than python. I’ve even had some luck using perl5 for long lived projects. Some of my scripts are 20 years old, nobody will want to dig into this old crap to fix it, so it’s best for it to just keep working.

    1. I run into the opposite problem: my scripts work on both Python 2 & 3, so I’ve been using #!/usr/bin/python. But most distributions still have #!/usr/bin/python as python2, while many libraries have now dropped Python 2 support.

      1. I think you’re loosely right in that the interpreter path should not be hard-coded in scripts, but I remember /usr/bin/python standardized nearly two decades ago. What I don’t understand is why scripts don’t specify python2 or python3, which they very easily could. I haven’t seen a python installation without these specific names for… hmm… perhaps longer than that standard existed.

    2. Yeah, the POSIX sh and awk standards seem to be aimed at preservation. I’ve been using Plan 9 shell which has barely changed at all since 2000, but it’s limited. The shell is really simple and powerful, but lacks extensions such as arithmetic. (plan9port & 9base ports; Plan 9 from Bell Labs & 9front OSs)

      I’d like to write an article on the value of long-term stability, but I have fatigue and mood problems. Nothing can grow in a sea of constant change…

  2. There’s a special place in Hell for people still deploying Python 2 code, it’s a Hyper V isolated Docker Container on a virtualised network. They’re just evil down there not stupid, Hellnet is still diallup only though, for reasons, refer opening statement of this sentence.

  3. Just this morning I spent 20 minutes troubleshooting a shell script because it complained about a missing python library. Turns out I was calling /usr/bin/python which didn’t have that library installed but I needed to call /usr/bin/python3. I was down the rabbit hole of the script running with a different environment.

    Anyway, I’ve found it pretty easy to update my python2 scripts to python3. Tends to be small things like new names for libraries. Long live Python3 I guess.

  4. I really wonder why always a snake is shown here. I thought it is common knowledge among hackers that the language is named after Monty Python, and not the snake. This always annoys the hell out of me ;)

  5. Hahaha I’m stuck doing this very migration for several projects at work currently.

    Tips welcome from anyone else doing this, it’s not even really my job role but you know how these things go :)

    Stuff I have done:

    * Setup a .bashrc with these aliases to help switching between Python2/3
    # Must set this option to allow expanding aliases
    shopt -s expand_aliases

    alias python2=’winpty C:\\Python27\\python.exe’
    alias python3=’winpty C:\\Python368\\python.exe’

    * Using the futurize command to auto-convert Python2 to 3 seems pretty good for handing the new importing and the simple print() changes but left me with an endless nightmare of bytes vs strings. The code I’m converting has a lot of XML reading that broke because everything was read in as byte strings: “type(var) = bytes” print(var) = b”Hello”. Converting these to Python3 strings means appending a .decode(‘utf-8’) method and the reverse string->bytes is done with .encode() method. This messed up a lot of string comparison + type problems that manifest in weird ways if you don’t realize the type change. Such is life in a dynamic language I suppose

  6. > That’s not necessarily a problem right now, but any bugs and security vulnerabilities discovered from this day forward won’t be fixed.

    While the core developers are doing everything to make that true, including using their trademark on the name “python” to send cease and desist letters, they ultimately can’t stop the open source community. In particular, Red Hat will be supporting and fixing Python 2 at least as long as its support contracts state, and the PyPy team already promised to support their version of Python 2 indefinitely. So no worries, just don’t use the “official” cpython and you will be fine.

    1. I should also trademark the whole dictionary.

      Trademarks are the poison pill to restrict free and open source software, with Redhat Enterprise Linux (RHEL) shows. They are in fact making free software non-free.

  7. Did some ATE stuff about 8 years ago for a former client- was mostly python2 and some C. Just before the covid19 fiasco, they sent me a SOW to do the same thing for python3/C++. So in all of these intervening years they have yet to change one single line of code or one single piece of test equipment? I procrastinated wisely – they closed down last week and will file bankruptcy.

    Still have to deal with py2 stuff – but am careful to do it in virtual machines, and advise clients to migrate; and no, I do not do py2/3 conversion jobs. Any py-dev is has be done in py3 for over two years. Otherwise it is done in C99 or assembly.

  8. Incompatibility killed many hardware and software projects and companies. What were they thinking when they started python 3 as incompatible version, is beyond me.

    If it works, leave it alone. If it doesn’t work, well then you made huge mistakes in making python 2. It’s one or the other.

    It’s too late now. But infamy will live forever.

  9. Never EVER introduce breaking changes to a language that many people use. Just don’t. You’ll end up with this. Inevitably. Yes, of course you have good reasons wanting to do away with the old, with its odd quirks and weird exceptions to the rule… but it doesn’t matter. If you introduce breaking changes, people will refrain from updating for literal decades. You’ll end up having to support both, no matter how often you declare the old standard obsolete, “legacy” or “dead”. It won’t actually die, ever. You’ll be haunted forever. Congratulations on cleaning up that language, though :-P

    1. “People will refrain from updating for literal decades”… probably.

      “You’ll end up having to support both”… doesn’t follow. You don’t HAVE to do anything. Let THEM take on the maintenance burden. If they’re not capable of doing that, and they eventually find that there is no computer that will run their code, well, that’s tough for them. Don’t make their problems into your problems.

      That’s one great thing about being a noncommercial project. You can tell downstreams to get stuffed if they won’t keep up.

      … and if you as a user find that you’re using software that hasn’t kept up with current versions of its dependencies, despite like a decade of warning, then you have learned something valuable about that software: it’s either unmaintained, or maintained by lazy, incompetent nitwits. Either way, you should drop it and use something else.

      Software is naturally dynamic, and anybody who expects to be able to write it once and use it forever is a fool. A dangerous fool, given how security tends to work.

  10. Don’t worry it all becomes obsolete when Python-4 comes out next year.
    It will be complete with the “never” statement as the alternative to the “while” and the “yahrecon” construct for fuzzier logic. It will be the new standard so those who like standards will have even more to choose from.
    My scripts are in bash.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.