the zero bit stream

programmer things

Python 3 Is Killing Python

Python 3 is easily the worst thing to happen to the Python community. I remember when I first used Python, I had been spending a lot of time in C++ land, and Python was like a revelation. I could open up a text editor and have a working program in seconds or minutes, not hours or days. I remember when Python 2.5 came out with a lot of neat new language features. I love Python, but I acknowledge that it has weaknesses, but that’s OK, all programming languages do. Its strengths are what make it interesting. While Python 3 has some tiny, incremental improvements over Python 2, it has lost many of Python 2’s strengths.

One of the great strengths of Python 2 is the long tail of 3rd party libraries to do, well, just about anything. Python 3 doesn’t have this. Yes, a lot of libraries have been ported, but ten times as many have not, and are not trivial to port. For example, you have a need to parse X, where X is something nontrivial to parse and not extremely common like YAML or JSON. There is a good chance that a parser has already been written for X in Python 2 and has not been ported to Python 3. Additionally, given the fundamental differences between Python 2’s byte string (str) and Python 3’s byte string (bytes), it will not be easy to port, in fact, it will be difficult to port and will require quite a bit of trickery to port it in such a way as to maintain Python 2 and Python 3 compatibility. So, you have a few choices, write your app in Python 2 (a deprecated language) quickly, port the library (and all its dependencies) which will take ten times as long, or use a different programming language that also has a long tail of libraries, but doesn’t suffer the Python 2 / 3 problem. Choice #2 is obviously not popular, because if it was, we’d have a lot of Python 3 apps in production, and much of the long tail of Python 2 libraries would be ported. Neither of those things is true. People either continue to write software in Python 2 or they pick another language that did not shoot itself in the face.

Another great strength of Python 2 was that programs written in it would almost always run on the next version of Python without much alteration. If your company runs on software written in Python 2 (as many do) it will cost you a great deal of money to port it to Python 3, because your requirements file is probably quite large and stuffed with all manner of libraries that have not been ported. There is no sane business reason to spend 100s of thousands of dollars or millions of dollars worth of engineering time to port to Python 3. You might as well ask someone to port their entire codebase to Ruby. Except, that would be cheaper. Now, if you are going to have to rewrite your software either way, would you choose Python 3? No.

Popular libraries that support Python 2 and 3 are almost all written in a subset of the languages that runs on both platforms. SQLAlchemy, one of my favorite Python libraries, does this well. Django does this, too, but not so well. This subset language, which I will call Python X, is not fun to use, requires weird hacks, and generally is less powerful than either Python 2 or Python 3. How fun is it to port existing Python 2 libraries to Python X? Not fun at all which is sad because fun used to be what made Python so great.

Python 2, sadly, has been deprecated. Python 3 languishes in disuse. The changes in Python 3 are small. Not much was gained, yet much was lost. For the past several months, I have been building applications and services in Python 3. I’m not blown away by it. It is very similar to writing software in Python 2, except that there is a much smaller pool of 3rd party libraries available. There’s really nothing amazing here. The Python community was supposed to be moving to Python 3 over the past few years, but it has become increasingly obvious that people are moving to new languages (or old languages rediscovered). Some of these languages have great features, like powerful type systems, pattern matching, better performance, better threading and concurrency, simpler FFI, nicer lambdas, and so on.

One solution is to fork Python 2.7, and continue developing the language, adding features in a backwards compatible way so large, unportable (due to financial constraints) Python 2 applications can continue to evolve and improve and bring value to the people and companies that invested so much time developing them. This is the correct thing to do (actually, it would be best if Guido and other leaders in the Python community did this officially instead of forcing a fork). Features from Python 3 that can be backported to Python 2 should be, and a Python 2.8 release should be made. Those few who have actually spent time to write new software in pure Python 3 can use a tool like 3to2 to bring Python 2.8 compatibility.

There are perhaps other solutions, but reviving Python 2 seems to me to be the correct thing to do. The Python 2 revival will not happen officially because those in charge of such things have shown disdain for users of Python 2. If the community does not rally and revive Python 2, Python 3 will after many years become the standard Python and many libraries will be ported (though most will certainly never) and many investments will be lost. The community will, by that time, have shrunk dramatically, and lost its former glory. People will move on.