The simple reason is that there was no compelling feature to reward you for upgrading. You'd spend a tremendous amount of effort for dubious return and (until recently) a smaller ecosystem.<p>1. Unicode support was actually an anti-feature for most existing code. If you're writing a simple script you prefer 'garbage-in, garbage-out' unicode rather than scattering casts everywhere to watch it randomly explode when an invalid byte sneaks in. If you <i>did</i> have a big user-facing application that cared about unicode, then the conversion was incredibly painful for you because you were a real user of the old style.<p>2. Minor nice-to-haves like print-function, float division, and lazy ranges just hide landmines in the conversion while providing minimal benefit.<p>In the latest py3 versions we've finally gotten some sugar to tempt people over: asyncio, f-strings, dataclasses, and type annotations. Still not exactly compelling, but at least something to encourage the average Joe to put in all the effort.
Because there's been not enough carrot and too much stick.<p>The only real killer feature of Python3 is the async programming model. Unfortunately, the standard library version is numbingly complex. (Curio is far easier to follow, but doesn't appear to have a future.)<p>On the down side, switching to Unicode strings is a major hurdle. It mostly "just works", but when it doesn't, it can be difficult to see what's going on. Probably most programmers don't really understand all of the ins and outs. And on top of that, you get weird bugs like this one, which apparently is simply never going to be fixed.<p><a href="https://github.com/pallets/click/issues/1212" rel="nofollow">https://github.com/pallets/click/issues/1212</a>
I recently went through a fairly large upgrade from JDK8 to JDK 11 and it was a bit of a pain -- lots of dependencies to update, etc. But very few code changes were required, and the static type system made it pretty clear when the codebase was broken -- it just wouldn't build. It still took my team several weeks.<p>Migrating from Python 2 to Python 3 is way worse than that -- code changes are required, and because Python is a dynamic language you may not notice bugs until you actually run the code (or even worse, until after you release it to production and some code branch that is rarely invoked somehow gets called...). In other words, the tooling and the type system are not confidence-inspiring and it's really hard to verify that you migrated without breaking stuff.
First off. Python 2.6 and 2.7 supported Unicode just fine. I had a large all-Unicode system in Python 2.6. You had to write u'word" to get a Unicode constant, and use a "unicode(s)" function here and there. Also, the part that remained "compatible" was that "str" remained an array of bytes, even though there was also a type "bytes" and a "bytearray".<p>Early Python 3 was hell for conversion. The syntax was changed for no good reason. u'word" became illegal. (That later went back in.) The "2 to 3 converter" was a joke. I didn't have the "print statement problem" because my code called a logging function for all debug output.<p>Many of the P3 libraries didn't work. (The all-Python MySQL connector failed the first time I tried to do a bulk load bigger than a megabyte, indicating that nobody was using it.) It took <i>years</i> before the libraries were cleaned up.<p>Python 3 got some really weird features, such as type declarations that don't do anything. I can see having type declarations, especially for parameters, but they need to be used both for checking and optimization. CPython boxes everything, which is terrible for numerics and is why most serious math has to be done in C libraries. My comment on that was "Stop him before he kills again."
Any non-trivial piece of code will probably be a pain in the ass to port for a more recent version of the language, and the level of PITA depends on the size of the project X size of the changes in the language.<p>Case in point, I worked in a project using Ruby. When we migrated from Ruby 2.4.0 to 2.4.6 (yeah, a minor upgrade), it broke spectacularly. Trying multiple Ruby versions, the change was actually introduced in Ruby 2.4.1. After some investigation, a change in Net::HTTP library from stdlib had a change that broke a dependency from a dependency. The fix was just a line of code (we just need to change the adapter used for HTTP communication), however it was two days of work for a minor upgrade.<p>My current job tried to migrate from Java 8 to Java 11. It also broke multiple services. This one is still in progress, months later.<p>Python 2 to Python 3 is bigger than both of those version changes (however it is equivalent to Ruby 1.8 to 1.9 changes), so yeah, it does take more time. And like some projects that are forever running Ruby 1.8 or Java 8 (or even worse, Java 6), we will have projects forever running Python 2 too.
Another data point:<p>According to my highly unscientific survey of the packages in Gentoo's package repo, there are roughly:<p>- 2500 packages that work with Python 2 or 3<p>- 1350 packages that work with Python 2 only<p>- 350 that work with Python 3 only<p>My methodology:<p><a href="http://dpaste.com/1M0TCV7" rel="nofollow">http://dpaste.com/1M0TCV7</a>
>Why Is the Migration to Python 3 Taking So Long?<p>For the same reason why migration to IPv6 is taking so long.<p>Both technologies don't solve immediate problems end users are facing. Instead they solve 'nice to fix' problems that few people care about.
In my current job, I can point out something that might be a contributing factor:<p>I work in an industry where there is basically one 800lb gorilla of a vendor. They update rarely, because their product is a mission-critical, life-or-death sort of thing. Their current product is heavily, heavily integrated with x.y.z version of software from a different vendor in a different segment, but also weighing in at 800lb. Yes, they specify x.y.z, not just x or even x.y. That software comes bundled with a Python 2.7.5 distribution.<p>Imagine my woes trying to get pip running, which unhelpfully suggests I upgrade Python. Cannot seem to find any other path to even get pip going because of what I call the "lol just upgrade n00b" factor. Perhaps that information once existed but I cannot find it.<p>So, I am stuck on this version because of some pretty tight integration, at a couple of removes. I think the vendor-linkage can cause some "drag" that folks who work in a greenfield environment might not be thinking about. It can be unfortunate but there it is.
Py3 is for all practical purposes a language fork of Py2. So it doesn't really make sense to talk of a "migration". If Py2 becomes unworkable somehow then people will rewrite stuff. Some of it might even be in Py3.<p>Considering all the stuff that is written in Py2 I really don't see it being out and out abandoned. That wouldn't really make any sense. With computer languages stuff never goes away.
What do you mean taking so long? The original target date, proposed by Guido, was Jan 1, 3000. Looks like we're 980 years ahead of schedule! :-)<p>I say this in part because comedy, but also because it was anticipated to be a long project. It was originally called "Python 3000".
Because it's not just syntactic changes, it's implied-semantic changes too. You can't mechanically transform a project and know that it'll work.<p>And you can't do it gradually, so it's all-or-nothing. (yes, "six" exists, but you still execute one way or another)<p>And you'll have to change the versions of all your libraries, which is not usually a smooth experience in the Python ecosystem. (this is another place where it's "all or nothing", since six can't help you if your dependencies don't all use it + use it correctly)<p>---<p>It's a <i>huge</i> risk with <i>huge</i> cost for already-working, running code. For new stuff, sure, write it in 3, but 2.7 works fine and has the added benefit of being <i>very</i> well understood by this point.
In the academic data science-y world, the transition has passed the hump. In other words, where I was reluctant to switch a few years ago because some of my basic tooling was still in the 2 land, today the critical mass of important libraries has been ported and updated. Most of the cutting-edge docs and tutorials (Google's GPT2 for example) default to python3.
Because they broke backward compatibility in very annoying ways without providing a fallback mechanism.<p>I still haven't forgiven them for killing the print statement, which could have peacefully coexisted with a print() function.
Simple answer. Updating legacy code. If it works now why upgrade? Stability is more important than some new features of the language. Granted that has its downfalls via security issues but stability wins<p>If you have a hole it's hard to dig yourself out of it. This is why I prefer modular apps instead of monolithic codebases. You can upgrade piece by piece. Otherwise it's all or nothing and dangerous
I haven't migrated to Python 3 simply because I see no reason to go the the pain and hassle of porting my existing Python code. Python 3 doesn't give me anything that I want or need badly enough to put that much work into it.
I never knew if this was a cynic's answer or truthful, but I was told by my manager at one point that RedHat's OS is superglued to python2 and spends a lot of money to keep python2 in good working order. I highly expect it's a cynic's response and please read it as such until someone in-the-know can retort my post.
I now work on a python 3.6 codebase. Something like 100k lines of code. in practice 80% of the code was written for 3.5.<p>However, barring speed improvements, there isn't much to offer, apart from unicode, f strings and annotations.<p>If python 3 had proper multithreading, that might have been worth breaking backwards compatibility for.
The key inflection point was around Python 3.3 when enough bridging technologies and tools came along to either migrate code or else write code that supported both languages. Things like adding the u'string' syntax to Python 2, the creation of six.py, all the various features in the future package. That gave a much smoother transition path and enabled crucial libraries to work in Python 3, which then let everyone else migrate too.
The upward migration is imminent for ALL CONNECTED applications and not just Python 2 to 3. An issue I've seen with PIP (that must be relevant to other platforms as well) is that version-locked packages are for software that can no longer communicate with the actual SaaS/API because THAT layer has changed. It's really THIS that is forcing conversion of Python 2.7 to 3 because API vendors will stop supporting old software while they continue breaking their own interfaces. The alternative is the end user or FOSS picking up the slack but that's only going to happen for SOME of the API's. In the end it will be cheaper (albeit still painful) for companies to upgrade their code to Python 3.<p>I have a lot of Python 2.7 code that I wrote years ago which has been running smoothly and my team is generally going to rewrite rather than "convert" because I really don't trust conversions. I'd rather see all bugs upfront rather than hidden in the fog.
The thing is python3 IS a better language. Unicode is very important for me, as i deal with a multitude of languages. For a good comparison, see how PHP failed unicode with PHP6 and we still deal with an insanity that is the mb_ functions. In python this is a non issue, and its a very nice language to work with.
In my experience, the biggest issue that I face is "what do you mean by Python 3?" I count 4 minor versions which aren't fundamentally broken, and I encounter them all on a regular basis.<p>A lot of my code is performance critical, and, for example, I'm still salty about dictionary operations taking O(log(n)). But the proliferation of active minor versions makes it very difficult to write portable, performant code.<p>It's become a sticky wicket. I want to migrate to Python 3 (and, by and large, I have in most of my projects). But what version do I target? Will my dependencies make the same choice? Or does "migration" turn into a sisyphean task? It's becoming burdensome enough that I'm contemplating abandoning the language for something more stable.
About 10 years ago I started learning Python. I double-timed across both versions. I decided to land on v3 for good. I haven't looked back. Granted that Big Corp cannot have such flexible actions. I reserve sympathy.
The same reason there is still a ton of legacy PHP 5.6 code.<p>Migration in interpreted languages that implement major breaking changes is really tedious.
> most large organizations, outside of the hype cycle of technical news posts, move much more slowly than the press or blogs would have you think<p>That’s the reason I am so upset with today’s JavaScript ecosystem - things move so fast that good technology is being deprecated and changed constantly which breaks all kinds of things in other places.
As somebody who only occasionally uses Python, the fact that the default `python` binary on my system resolves to Python 2.x and I need to specify `python3` to invoke 3.x, means I am quite often mistakenly using Python 2 instead of 3.<p>How can we expect Python 3 to become the default if Python 2 still asserts such dominance?
Or, in the case of my employer (and new ecosystem for me), we are using Jython which AFAIK has no clear plans or path to support Python 3 at this time. Iron Python has started work to support 3 but it's still in development and seems to be a ways off.
We're still waiting for Maya to switch. It's still using Python 2, and Autodesk keeps putting off the transition, partially because it'll break the scripts of all their downstream users.
Personally, I don't see the need to migrate entire code bases if there is no need. I think that much is obvious. Perhaps the focus should be put onto pivoting instead. That way it doesn't leave your dev team on the hook to go back and change existing code bases in python 2.
In my organization, business needs overrule technical details. Management didn't want to spend the resources until forced to do so, rather focus on revenue-generating work. Can see it both ways I guess. We have recently started upgrading our codebase to support 3.X
The 2to3 tool should add .decode(‘utf-8’) to every string manipulation, even better Python 3 should have a flag to make that the behaviour and <i>even better</i> that should default to on.<p>So much effort wasted doing this in a large codebase. And what do you get for it? It’s just not worth it. Nobody actually needs Python 3, it was foisted on them by the developers. What everyone really wanted was Python 2.8.
[copying comment from an older HN thread, not speaking on behalf of any employer, opinions my own]<p>I think many people underestimate the challenge that the 2 to 3 migration presents for large enterprises. The core issue is that even though the migration for any given module is normally really easy, the total effort required to migrate is still essentially O(n) in module count/file count, because even with current tooling you still need to have an engineer look at every module to do the change safely. Even if it only takes ~5 minutes per module to make the changes and validate that it works correctly, this becomes a giant undertaking when you have tens of thousands of files to migrate.<p>The fact that it takes a long time also creates other problems. Your business isn't going to hit "pause" on other development, so there will be changes constantly introduced into modules you've already "swept". It's going to be hard to make sure 100% of your engineers and code reviewers are knowledgeable about the specific requirements to make sure the code works in both 2 and 3, so you would really like some automated safeguards to make sure they don't introduce anything that won't work in 3. Pylint helps with this, but won't catch everything. Unit tests are obviously essential, but:<p>1. Even a well-tested project won't have tests that cover 100% of code paths and behavior.<p>2. You're stuck running the tests on both python2 and python3 for the duration of the migration, which doubles the resource (compute, memory, etc.) cost of your Python CI and regression testing infrastructure for the duration of the migration.<p>Most big companies have passionate Python advocates who really want to be on Python 3, but the scale of the problem and the lack of tooling to tackle it with a sub-O(n) amount of effort make the overall project risky and expensive for the business.
I honestly don't care as long as I don't have to deal with Python 2 code bases anymore. The important point is that all of the popular open source libraries and frameworks are ported.
Python, unlike a C executable, could hypothetically stop working tomorrow. Researchers who have code that works/businesses don't give a shit about the esoteric differences between py2 and py3, they just want their stuff to keep working. This is similar to the banks still running Cobal backends, I don't know why everyone cares, I guarantee multiple servers out there are running executables that couldn't be rebuilt, but those don't curse you out on terminal every time I turn one on