Naftali Harris

Why I'm Making Placeholder

November 30, 2016

For the past two months I've been spending half my time on Placeholder. Placeholder is a backwards-compatible Python interpreter that runs Python 2 code and C-extensions exactly as-is, while also allowing Python 2 programmers to use the most exciting new language features from Python 3. These new backported language features include async/await syntax, function annotations and typing support, keyword-only arguments, and new metaclass syntax, among many others. I use Placeholder as my system python now, and haven't had any problems running my old 2.7 code or using packages like IPython, pip, numpy, pandas, requests, and flask. I've been enjoying the new language features--I especially like underscores in numeric literals!

(Note: the name of this project is temporarily "Placeholder" while I search for a better long-term name).

I've been working on Placeholder (not an official Python release) because I want to give all the people who use Python 2 access to the Python 3 language features, which I think are actually pretty cool. By most accounts, somewhere between the majority and the vast majority of Python code targets Python 2. Some even claim that all of Python 3.x put together is about as popular as Python 2.6, the outdated version of Python 2. At least personally, almost all of the python I've ever written personally or professionally uses Python 2.7 or earlier.

Now, unlike a few "Python 3 skeptics", I actually do believe that in a vacuum Python 3 would be a superior language to Python 2, including Placeholder. That is, if Guido were to introduce Python today for the first time, and offer everyone the choice between Python 2 and 3, I would vote for Python 3. The removal of old-style classes and the unification of int and long seem more Pythonic to me, ("There should be one-- and preferably only one --obvious way to do it"), as do the overhaul of Unicode and the raising of TypeError's for wacky comparisons like "1 < None", ("In the face of ambiguity, refuse the temptation to guess."). The biggest syntax change that I don't like in Python 3 is actually the removal of the "print" statement--it's just easier to type "print x"!

But "practicality beats purity": a programming language's success should be measured by the degree to which it helps its users be productive. And the majority of Python code written does not run under any of the 3.x interpreters. This makes it harder for its users to be productive.

One could argue that the loss of productivity required to port your code to Python 3 will be offset over the long term by productivity gains from the new language features or from the removal of the older language "impurities". For many people who have ported their code to Python 3, that may well be, although empirically the companies and people that still use Python 2 don't seem to think so. That there would be disagreement about the value of porting makes sense; the productivity gain or loss of course varies project-by-project. At least personally, though, I haven't felt much pain from the language impurities in Python 2. While having both ints and longs bothers me on an abstract level, for example, I don't remember ever dealing with a bug it caused. I don't think I even spent much effort handling both ints and longs in my numutil package.

So I'm making Placeholder so that people with Python 2 code can use features from Python 3 to be more productive.

As I write this, there are only a few major language features that Python 3.x has that Placeholder does not. These include argument-less "super()", the "nonlocal" keyword, "raise from" syntax, and some unpacking generalizations. If these are backported to Placeholder, then Placeholder would be able to run most Python 3.x code in addition to running all 2.7 code. Unlike 2.7 code, Placeholder wouldn't be able to guarantee exact 3.x compatibility, since there are some python scripts that will run under both Python 2.7 and Python 3.x but produce different output, and Placeholder chooses the 2.7 behavior in these cases. But adding these remaining Python 3 features would greatly simplify running code targeting Python 3, and allow people to use Placeholder to run a mix of Python 2 and 3 code.

You might also enjoy...