Python 2 Is Dead
enricozini.org
enricozini.org
Sometimes one's only purpose in life is to serve as a warning to others...
Eventually settled for none. I didn't know that at the time, but later it proved to be a career defining moment.
Definitely changed the course of my programming career.
Nothing really wrong with that, but it should have been called "Cobra" or something. And the weird jihad for killing off Python2 should never have happened. If everyone moved to Cobra on their own, great. But there should have been no beatings.
The act of killing off V2 gives downstream developers the right to stop supporting it; regain some focus.
Seems like a strange way to give developers more "rights".
This way there's no expectation, I get to wash my hands of it all. And without an awkward "I'm moving to Viper now chaps". It's a system update paradigm that people understand.
But when you have a few dozen customers on a single product, supporting edge-cases that require core forks becomes incredibly hard. Especially when you need modern Python features.
We tried it. It doubled TTL for simple patches, and meant the Py2 version fell behind in terms of gross features. It was expensive for us, worse for the customer, so we dropped it and moved to a unified core. We had one customer threaten to leave but they didn't. Somebody in their IT department rubbed two brain cells together and agreed with our assessment.
A customer might leave over this sort of behaviour, but again this worked out to be more cost effective, so we would probably do the same when Python 3 is EOL. Wheel keeps turning.
This was the best way to do it. Slowly and painlessly. Any project that matters is now on 3.
For a bad transition, look at Perl 6, a debacle so big it was renamed Raku and became a different programming language.
But it was still full of unnecessary breaking changes.
- The `print()` function is nice, but they could have left in the `print` statement for a transitional (deprecation) period. Or left the `print` statement in, and advise against its use.
- A lot of the incompatibilities are just stdlib modules being moved around unnecessarily. They could have made both import paths work for a transitional (deprecation) period. Or let the old paths continue to work forever, and just document usage of the new paths.
- All the new features in Python 3 (async, nice helper functions, etc.) are compatible with Python 2. They could have added them to Python 2.
The only true breaking change was unicode literal strings. But again, that could be handled with a slow transitional (deprecation) period. The Python 2 stdlib could have been made compatible with both types of strings (as nearly all third-party libraries have). And users could have been told to `from __future__ import unicode_literals` for a transitional (deprecation) period, to ensure their code is compatible before it becomes the default.
Basically Python 3 could have been a single hard breaking change (unicode literal strings), with a smooth transition. Instead they decided to make Python 2 and 3 diverge from each other, making it harder to do the transition.
They did, it's from __future__ import print_function. python2.7 was, essentially, the transitional deprecation period you mention, and it lasted a decade.
> A lot of the incompatibilities are just stdlib modules being moved around unnecessarily.
six.moves
> - All the new features in Python 3 (async, nice helper functions, etc.) are compatible with Python 2. They could have added them to Python 2.
This assumes a level of similarity in the py2 and py3 codebases that isn't true in practice. There are different bytecodes and 3.0 only optimizations. Backporting some of these is possible, but not a reasonable burden.
>The Python 2 stdlib could have been made compatible with both types of strings (as nearly all third-party libraries have).
I don't know what you're working with, but most third party libs aren't compatible with both types of strings. They're compatible with str or bytes, but not both except in rare and usually wrong cases.
Importing unicode literals only sometimes solves the issues, and often times introduces different problems.
Or do what javascript did: stay compatible with the stupid old way, but build a brand new language on top of it.
Where do you think the idea for `"use strict"` in JavaScript came from?
use v5.8;
use strict;
use warnings;The print statement dates to antiquity (cf. BASIC) and could certainly coexist with the print() function. It was a nice and friendly piece of syntax whose removal was entirely unnecessary.
Now that Python is free of GVR, perhaps we can restore the print statement to its rightful place in the language! ;D
At first glance, you're right. But if you take a closer look, from a purely pragmatic perspective, there are now at least two coexisting ecosystems in two different languages, peacefully sailing along.
Python 2/3 is in this kind of weird twilight zones that the two versions are far away enough that you can't have a smooth transition like in e.g. C++, Java, Rust, Go, etc., but still close enough that there is not a clear cut like in Perl5/Raku. So for a few years, one had to juggle with some of the libs that were 2-and-3 compatible, some that were 2-only, and the others that were 3-only.
C++ et al. let your code evolve Theseus ship-like; Perl makes you build a new ship; and Python tells you that your ship should be OK if you repaint that thing, change a bit of that one, oh, and by the way, you'll have to check very carefully your bunkers, because the boilers will explode if every coal nut is not Unicode-compatible.
Was it really though? Speaking as somebody who considered learning Python several times over the course of a decade I was seriously put off by the protracted uncertainty around 2 vs 3.
There was a long period - years long - where everything that "mattered" seemed to be supported by and available for Python 2 and there was a ton of FUD, along with genuine issues, about incompatibilities with Python 3. When I asked which version I should learn I felt like I couldn't get a straight answer.
I never had a strong need to learn Python: I just thought it might be a fun and useful thing to do, because people seemed to like the language. But I wasn't interested in investing time in something that might wind up unsupported in a few years, and because I didn't have any serious need for it, it wasn't worth digging through the morass of misinformation to get to the truth.
As an outsider it was extremely unclear to me which version of Python would be actively supported for the long term. 20:20 hindsight says 3 was the future but - and maybe this is just bad mar-comms - back then it seemed like there was a reasonable chance it was either going to be a dead end or exist perpetually in this weird no-mans-land of "not quite ready for prime time".
Had I learned it there's a good chance I probably would have used it for something more serious by now. But I didn't, and so I have to disagree: it was done extremely poorly.
And yet Python is still one of the most popular programming languages, with its popularity and use growing.
Theoretically it could have been done better, but it was going to take time no matter what approach you took and it worked out in the end.
[1] http://python-notes.curiousefficiency.org/en/latest/python3/...
Fractured community Lost trust Endless bikeshedding
All for very little objective gain.
I was using it to an extent in 2009. (I'm sure I was using it before that.) At which point it had only been 9 years in development.
---
You can have it fast, good, or cheap. Pick at most 2.
Since Perl 6 was entirely volunteer driven it was always going to be cheap. So the only real choice was between fast and good.
I'm glad the choice was to make it good rather than fast.
We could have gone the Python route where they chose fast. Only they didn't really even manage to do that much better than Perl6.
---
And what did Python get, a language that is only slightly better in a handful of ways. (Every one that I've heard of is reminiscent of one that Perl5 has dealt with over the years without breaking backwards compatibility.)
Perl6 meanwhile is a large step that questions long held beliefs of what a programming language can even be. It calls into question what parsers can be, what regexes can be. It calls into question why language divides exist. Why can't a language be at both ends of the spectrum at the same time.
Even if Raku doesn't take off, it will likely be a source of inspiration for future language designers. (It already has to a small degree.)
Whereas Python3 is just a slightly nicer Python. One that not everyone has transitioned to yet. Some may never. (Some have even transitioned to Go instead, since it has very similar semantics.)
---
There were also some health issues during the Perl6 project which held back the progress to a significant degree. We don't know how many years that added to the total.
https://bugs.chromium.org/p/chromium/issues/detail?id=942720
I'll be dead in my grave before I recognize anything past 5.8.1.
Just like how they still haven't made The Matrix 3.
Sh. Quiet, you. :)
python3: Oh, sorry, you used a feature that was added in 3.x and this system has 3.(x-1) so now you get SyntaxErrors, or worse, random runtime exceptions.
If you can target a container, buildpack or a specific platform python3 is fine, but it's been terrible for developers and users since day one. At least, it's been terrible for me, which is why I still have a pile of stuff to port to python3.
It's fine for something like go or rust to add new features in a dot release, where you just need to upgrade your development hosts. Besides, if it compiles it will work, no surprises later.
But python3 adds new features in 3.5, 3.6, 3.7 and then immediately breaks all new code on older systems.
Used f-strings? Now your code is broken on 3.5.
A new feature used the walrus operator? Now your code is broken on any system that doesn't have 3.8 yet.
And 'dead' python2 keeps working.
> python3: Oh, sorry, you used a feature that was added in 3.x and this system has 3.(x-1) so now you get SyntaxErrors, or worse, random runtime exceptions.
Maybe you were used to Python 2.7 only as "Python 2", but when it was in active development, major 2.x releases had the exact same thing. I had some serious troubles when the latest version of RHEL was on 2.4 while the rest of the world had 2.6 with very large changes. There were all kinds gross hacks just to make things work on an older, common version.
Personally, as a developer who has been working on software for a few decades, I've gotten increasingly irritated with the growing churn of platforms today and the astonishing waste of time for everyone who has to deal with it. It's hard to hit a moving target or build on a shaky foundation, but that's what the state of software seems to be today. Instead of platforms approaching stability and spending time on the actual problems at hand, countless developer hours are wasting solving problems created by others "pulling the rug out from under them".
I guess the younger generation of developers just hasn't felt enough of that pain yet, or they're overeager to try new things without thinking of the consequences. I've always taken the conservative approach and as a result some of the software I've written has needed little if any new attention in decades. Some utilities I wrote 25 years ago (not in Python, obviously), I still use regularly. "It's not the tool, it's how you use it."
But you're missing the same point that the parent commenter is missing - stability only came because Python 2 has been sitting at 2.7 for so long.
And you're also missing the point that you can have the same stability by sticking to 3.6 or 3.7 or 3.8 or whatever your fancy is. If you stick with 3.7, I assure you that 3.7 will remain exactly the same and no one is going to pull your rug out from under you. Just don't upgrade.
But don't ask for new features either.
You can always stop now if you want. Download the versions of everything you need and never change. But you'll miss out on the cool new hotness that you're wanting everyone else to miss out on if they stop changing too.
Why doesn't any recent programming languages implement a proper condition system for example? It's not like working implementations hasn't been around for decades.
This industry has a severe case of inability to learn from history so I strongly doubt we'll see things settle down in the near future.
But I mean that since python2.7 came out 10 years ago, python2 has been a stable platform for building things.
Parent seemed to be talking about the reverse: going backwards, and implying that 2 didn't have major new features, even though it very much did.
Not 100%. For example, using `async` as a variable name works in 3.0 but not in 3.8, where it is a keyword.
https://github.com/search?q=remove+%22walrus+operator%22&typ...
if (diff := coord - lower) < self.view_dist:
I would've assumed walrus would've only been used at the top level of the expression, not nested inside a conditional!The response was they don’t have enough manpower. The though ignoring deprecated stuff a few releases doesn’t sound particularly hard. I suspect Guido just likes it that way.
Btw, almost no one supports forward compatibility.
The difference is the scope of the breakage. Python 3.0 broke every project. Python 4.0 certainly wouldn't, they are very timid now. In comparison, these breaks are tiny in scope.
It really helps if you think of the versioning as 5.0.x, 6.0.x of Python3, then semver can be applied and you set your shebangs accordingly.
If you use python3 it might randomly fail, if you use python3.8 will fail with 'No such file or directory'
But then if you're trying to write portable Python 3 code without any need for the end user to be pyenv-ing stuff, you probably don't want to be writing 3.8 - off the top of my head, Ansible, for example, targets Python 3.5 for this reason.
I'm not defending this btw, modern Python development is painful, and I taught myself to code in Python, so it hurts to see my first love so.
I guess it would be nice if Python came up with something like Java's source/target which errors if you're using incompatible features.
That second, lower gorilla comes with its own 2.Y.Z version of Python installed and a help page in a large, bold font explicitly forbidding upgrading that Python 2.Y.Z version, lest some dire things happen. And so in my little niche of the world, Python 2 Is Alive. I am not holding on out of stubbornness.
As I learned in a previous job, software lives for a lot longer than expected or even desired, like some declared extinct species popping up decades later.
I disregarded Python 3 for a few years, then started accepting pull requests for Python 3 support on my packages when Django started to support Python 3, added it to the CI build matrix.
Then, I started to code compatible with Python 2 & 3 while keeping Python 2 as my main Python (private codebases). A few years later (not so long after Arch Linux made Python 3 the default) I started using Python 3 as main Python, contributed to other packages for Python 3 support as I needed it.
It was hard, until I became sufficiently efficient at it, then it became a joy to have "such easy" contributions to make to the Python ecosystem, note that at the same time I was doing the same with Django versions which did break user code often on upgrade.
Perhaps it's because I worked so hard to upgrade codebases during Django 1.x days, and Python 2 to 3, that every upgrade now seem so easy, anyway, it basically feels like I have nothing to do anymore given the current state of the parts of the ecosystem that I depend on.
As of this day, I must admit that the whole operation has been a great success. I could jump in the train when I felt like it, and nowadays upgrading has never been easier, asyncio has become really fun to use with Python 3.8, Django 1.x days were hard on users to upgrade, but since Django 2.0 it's mostly been a no-op for me, most of my Django 2.x codebases just work on Django 3.0.
For those who had left Python or Django, or decided not to try it at all, it really seems to me that now is the best moment than ever to try it out, again or for the first time. Yes it was pretty hard, yes it took a while, but I really feel golden about the current situation. I'm glad I sticked with Python and I see people coming back to it, it's really useful for a wide variety of use cases.
There have been other painful upgrades (Swift, Rust) but these have been in younger languages with less established codebases; both have since shifted to a mature-language model. Python3 is unique in attempting to aggressively evolve a very mature language with deep established codebases, and has paid a heavy price.
Pay us money.
Personally it’s long been dead to me.
except for COBOL, which has the Schrodingers' property of having been (called) dead for 40+ years, but also somehow powering the world and its' infrastructure.
Does "subsidized zombification" count for a programming language being otherwise dead?
Side Note: 20 years ago a SciFi book introduced me to the idea of "Software Archaeology". These days, such a term is slowly gaining traction as a job description. I've had to professionally dabble into this myself from time to time.
It turns out that Pypy will have Python 2 support. I don't know the details but it sounds like you'll be able to run py2 code using pypy (not pypy3) for N more years.
I am surprised that even 1,000+ languages (at least 50+ mainstream) haven’t satisfied all the wishes and itches. May be that is humanities curse! Creative people constantly want to create a new language and redesign everything while bigger and better problems remain unsolved.
Python 2 vs 3 just seems like yet another thing that breaks up the creative talent pool to waste time solving the same problem in two ways.
LLVM is the first thing I have seen that removes at least some of this duplication. But I hear even Rust is looking at alternate backend! Go doesn’t even use LLVM, all for good reasons I am sure.
A new programming language is like a new material. You can build chairs and tables in wood. But when a new metal is introduced, is it worth to "duplicate" the work and build chairs in the new material? Maybe, who knows. You may end up with a chair that has surprising new properties, impossible to have in wood. Or maybe it is worse in any measurable way, but some people may still prefer it for some reason. Would you complain to the discoverer of a new material that they should not build chairs in that material, because chairs are already solved (by using wood), and they are just losing time by reinventing the wheel?
Technology advances by the continued reinvention of the wheel. Rewriting old algorithms in new languages is a beautiful part of that.
What I might agree with is that interoperability is something that should be considered more going forward. I'm unsure about some of them, but Rust focuses a lot on interoperability via FFI, Go's FFI story is bad, as far as I know, Nim's is decent, and I don't knwo about Dart or Swift.
The top languages are all virtually identical. There's so little difference between, say, Java and Python, despite there being so much difference. So maybe there are 50 "serious" languages, but they all fall into a few buckets. There's less meaningful diversity than it seems, I think.
Most people who actually used Python 2 have zero issue using Python 3. And most people coming into the Python ecosystem now only ever experience Python 3.
The people whining about Python 2 have legacy codebases. And, they have a right to whine, but Python 2 at least will continue to exist. Look at Visual Basic 6 codebases by contrast--more and more of those break with every Windows release.
This is also way different that say the ObjC to Swift transition. Apple simply said "Move, or don't. And if you don't we won't ship your app." And the community moved.
> Regardless of Python 2 vs 3, what is sad is that every new language, be it Go, Rust, Swift, Dart, Nim whatever is dividing whatever set of ‘good, smart, and creative’ engineers we have into smaller group each implementing their own sorting algorithm in their own language.
Sorta, but the whole point of a language is to have a strength that outweighs the negatives of creating it.
If I go through the Tiobe index and look at relatively new languages (there aren't that many in the top--Python, Ruby, and Javascript hardly count as new):
Swift is ObjC moved forward. That one was never going away.
Go is for concise networky client/server thingys. Okay. That's better than most other languages and has some large codebase improvements.
Rust is the only non-GC language in the pile and it aims to be a better C/replace C++--an arena that has been absolutely stagnant for 30+ years.
<dons asbestos suit>
Dart ... okay, you got me. I have no idea "Why Dart?". Every time I interact with it it seems to look like a crappier Clojure with Google foisting it on the world. When your function closings look like this:
);
},
),
);
}
You have Lisp-envy. I often wonder if this is just some team inside Google going: "Android Studio is absolutely terrible, anything is better, but we can't budge the glacier. We need to route around the brain damage."D was meant to be a better C--but it took far too long to get a useful non-GC subset so never found its niche.
Scala--Meant to bring Haskelly goodness to the Java ecosystem. In my opinion, overreached, never really achieved its goals and now is competing against better languages. It took FOREVER until the whole Actor system worked decently in Scala, for example. To be fair, it also appeared in like 2000(?) back when the Java language ecosystem was basically crickets chirping. The JVM has improved a lot since then and made language development a lot better.
Kotlin--presumably in the right place at the right time. A modern Java before modern Java. And appeared at the point where Google needs to make sure to have an escape hatch against Oracle if required.
Groovy--Possibly the worst language to have any traction. However, most people's interactions with Groovy come about when they have to fix something broken in the absolutely horrible Android Studio build system. Friends I trust say that Groovy isn't really that bad (but not that compelling) but that, yeah, the Android Studio Build system is a horrible exemplar.
If someone can explain this dependency of the package management system or the behavior I saw, I'd be very grateful.
(picture of utopian society)
Unless the code base has a very very good set of unit tests, which is unlikely in practice, it is very risky to do automated conversions.
Whereas the same situation with Java, Go, Rust etc would be slightly better. Sure you would still have bugs but lower probability.
It's yet to be seen how this runtime will be maintained in the future. Of course, given the enormous usage of python2 it's clear that it will be possible to use it far into the future. But it's really an unprecedented situation where an enormous software platform is abandoned by its developers. If this were a commercial product, it would filter through the long tail of software graveyards like Oracle and Computer Associates. I imagine the main annoyances in the future python2 landscape will be vendor fragmentation and diverging implementations.
I've never understood where this mentality comes from. I have programs 30+ years old, and still use them because they work perfectly fine.
That’s “where this mentality comes from”.
Telephono mobili Android decurrit
$ /usr/bin/python2
WARNING: Python 2.7 is not recommended.
This version is included in macOS for compatibility with legacy software.
Future versions of macOS will not include Python 2.7.
Instead, it is recommended that you transition to using 'python3' from within Terminal.The truth is that Python3, as a new language incompatible with Python2, was a mistake. I'm sure it was well intended, but here we are.
https://click.palletsprojects.com/en/7.x/python3/
and here, have a nice sandwich of this:
https://stackoverflow.com/questions/57652720/runtimeerror-cl...
or this bullshit:
https://bugzilla.redhat.com/show_bug.cgi?id=1404918
The truth no one wants to hear is that Python2 did Unicode right (or as well as could be expected), while Python3 is a train wreck, even if you just stick to LANG=C and ASCII.
And no, for people who actually have to use unicode, python2 didn't do unicode anything like "right". Python2 did unicode "right" for the people with LANG=C and ASCII. Those people are generally wrong.
Even pallets notes
>Misconfigured environments can currently cause a wide range of Unicode problems
The keyword there is misconfigured. Your system is misconfigured. Fix it (by making your locale correct). Then the problems go away.
And no, LANG=C isn't wrong. Your software has one job, to at least be correct for LANG=C. If it can't do that, it sucks.
Python trusts the system, and the system lies. It's your fault for lying to python. Configure your system correctly, don't lie to your tools and then blame them.
Lang=C is the realm of English only 70s crap programs. You shouldn't use it. Use a modern encoding that supports modern characters.
The beauty of LANG=C is that it's the only true lingua franca of modern computing. It's a place where all software and programmers can "meet" without privileging any particular locale.
We have 'gettext' and friends for speaking to humans in particular locales. Embedding i18n into core system design just doesn't work.
This doesn't matter. I'm not sure why you think this matters or what problems will be caused, but a server using a unicode locale (C.utf8 or en.utf8) doesn't localize things for those clients, it just is able to not crash when printing their usernames to log files.
The usernames could be from a variety of locales. If showing them in that form is seen as valuable, they'll each have to be decoded in their appropriate locale. Using LANG=C doesn't prevent this, it encourages it.
Beyond that, as you point out, Unicode provides lots of new opportunities for crashes. Indeed, one of my favorite ways to crash software (software almost invariably running under a "proper" locale) is to feed it a string of (non-ASCII) Unicode. Boom.
No matter the approach, you must code for correctness and deal with all input. For Unicode, you must always allow for decoding failure.
You realize that locales and encodings are different right? En.utf8, c.utf8, and fr.utf8 are all different locales, but are all utf-8 encoded. They'll all work correctly when printed on a machine with any other utf8 locale. The differences arise in things like sort order and regex, where c.utf-8 might be best for a server if you want C or ASCII like functionality.
> Using LANG=C doesn't prevent this, it encourages it.
Well no, because you don't know what encoding each person is using. Either you guess which is error prone, or you have to control the other endpoint so that they include the encoding. But if you control the client, just use utf-8.
Pretty much no software does what you suggest. Go and rust, for example, go further and entirely ignore the system locale and just always use utf-8 for everything. People don't complain.
But my God, could this shit possibly be any more byzantine?
(And why doesn't LANG=C just cause c.utf8 to be used?)
Trying to wedge Unicode in at this level is a recipe for disaster, and after all these years, Python3 still doesn't have a reliable, coherent story on this.
But not windows, or a number of filesystems. Hell the vast majority of the time posix filenames are ASCII, and therefore utf8 compatible.
The rare cases where they aren't break all kinds of other tools because...
> Trying to wedge Unicode in at this level is a recipe for disaster,
Blame every terminal emulator and os in common use. They all display filenames in unicode. So pythons in good company here.
Since you have to display filenames, they need an encoding.
Ń̸̗̮̯͇͈͇̑͒o̸̧̭̯̖̾̐̔̈́̋̈́̈́͘t̵̖̹͙̟͑̈́̎̀͝ͅ ̴̡͒͌̋̾͆̒̎ȧ̴̬̰̪̮̩͉̐̈́̋̇̀̊̕ ̷̫͑́͑̕͠f̸̬̥̼̣̙͎͍͙̤͗͆ͅā̸̛̼̱̠̯͖̫͓͙͒̔͂̅͜͝ͅń̴̨̨̨̦̺̺͗͗̉̎̓̀͘͘͠ ̵̢̖̞͍̻̮͈̘͎̹̉̇̈͐̍́̂̂̀̂o̴̳͙̿͆͝f̵̮̙̞̰͖͉̰̞͕͑̍̀̄̎̍͜ ̵̛̗̙͓̰̹͇̍̒̋͆ͅU̶̧̯͇̰̞̮͋n̵͉̰̰̳̗͎̂͑̉͛̏͛̌i̵̢̢̪͂́̽̀͝͠c̴̢͇͙̙̲̯̫͈̪̀̌̓̂͗̚͜͠ơ̷̬͖̙̯͇̻̱͕͐̎d̶̛̤͉̻͆̋͋̂̀e̵̦̺̹̅͆̀͛̎̎̅.̸̡̟̰͙̮̱͍̼̾͊̑̅͊̚͝
this isn't actually how python 2 works either. `print("Ń̸̗̮̯͇͈͇̑͒o̸̧̭̯̖̾̐̔̈́̋̈́̈́͘)` will print the same string, since my machine's locale is utf-8. So python2 does the same thing as 3 with regard to machine encoding.
Thus Python3 failed (and frequently, continues to fail) to be a compelling upgrade to anyone but unicode purity fetishists.
This is something people are getting paid to do; maintain their codebase and keep it up-to-date.
Huh? No new project of any note is using 2. Everyone has either upgraded to 3 or never even learned 2 to begin with.
So, I suppose the answer to your question is yes--if you blindly update pip and/or you don't heed those warnings and pin your pip version accordingly.
Edit: I was curious, so I installed the latest Python 2.7 and pip. `pip install` (or any other pip command) shows a deprecation warning with info about dropping support for Python 2.7 every time you run it.
Do you want to come back to Python 3, bouncy bouncy?
Edit: this comment is meant to be funny but serious, it's not going anywhere, I've seen older tech that's still going strong in the "enterprise".