How to keep Python 3 moving forward

When I posted on Google+ about Python 3.4.1 being released it led to various comments on the post and it made me realize how far we have come with Python 3 and what people who have not ported yet can do to keep moving forward.

We have come a long way

I remember when we first released Python 3 the naysayers were all about how there wasn't a compelling reason to switch from Python 2. Those of us working on Python 3 said that the culmination of a bunch of little improvements led to a much more pleasant programming experience. But the naysayers continued to say that the state of the world in Python 2 was good enough for them, so they didn't want to switch (which is also, by the way, the same reason we hear from people not willing to drop support for very old versions of Python, so this is not a new viewpoint to python-dev and has been going for decades). Not having a compelling reason is fine and understandable as switching isn't done by snapping your fingers. But from the beginning we said to people that they just needed to give us time and the carrots for switching would come (while always trying to use a in-the-future stick of Python 2.7 no longer receiving official support from python-dev which we have done away with; read to the end if you don't know what I'm talking about).

I think Python 3.3 was where we started to see the tides turn from people mostly complaining that they didn't have a compelling reason to switch. And with Python 3.4 I really have not heard anyone complain that they wouldn't like to use Python 3 instead of Python 2. To me that's fantastic and means that python-dev has continued to do a great job in stewarding Python forward in a way that continues to improve people's lives.

Those darn dependencies

Now that people actively want to port, the question becomes why they haven't yet. The answer to that question seems to commonly be "a dependency is blocking me". There are three things you can do about this.

First, make sure your dependencies are in fact blocking you. I created caniusepython3 so that it's extremely easy to check if your dependencies have (not) been ported. There's even support to integrate caniusepython3 into your testing framework so you can have a failing test tell you that you are no longer being blocked downstream to your project. And on top of that you have Jannis Leidel's caniusepython3.com which not only gives you a nice web UI to run your checks on, but stable URLs to make it easy to check and badges you can add to your site so you can visually spot-check if you are still blocked. You do need to realize, though, that caniusepython3 is not perfect as it depends on either projects properly marking their Python 3 support on PyPI or me manually specifying that I project is ported. So if you ever come across a project that is actually ported but it isn't labeled on such on PyPI through its trove classifiers or there is a Python 3 fork, file an issue or send me a pull request (please be aware at the support has to be publicly available on PyPI as a stable release and not simply in their code repository).

So you've checked your dependencies and you are sure they are still blocking you. What can you do? The second thing you can do in dealing with your dependencies is to look for alternatives. For instance, MySQLdb is a dependency I hear about regularly that is holding people up. But did you know there is a fork of it that has done a port? Or how about that MySQL has an official driver written in pure Python that runs on Python 3 and adheres to DB API v2, making it practically a drop-in replacement for MySQLdb? This is where blindly relying on caniusepython3 to tell you if you are blocked is not always the best option when an alternative is available that simply isn't known widely yet.

Cryptography is another instance where an alternative dependency actually is called for. I have heard complaints that until M2Crypto or PyCrypto have not been ported to Python 3 they are personally blocked. The cryptography library is a new Python-based crypto library that's run by people like Alex Gaynor and Donald Stufft which is Python 3 compatible and might meet your crypto needs. Their site has an explanation as to why they felt the need for another crypto library for Python if you are curious. While this might not be a drop-in replacement like in the MySQLdb case I mentioned above, it might be worth considering changing your dependency to a more modern one that might have a nicer API.

But what if caniusepython3 was right and there is no direct port of a dependency and there is no alternative that makes sense? That brings up the third thing you can do, which is help make a port happen. The easiest thing is to politely ask for a port. It's quite possible a project doesn't realize that they have users who would really like to see a Python 3 port happen, and they won't know if you don't tell them. Obviously the next step beyond that is offering to help with such a port, but at least asking for a port requires little work on your part and no longer-lasting time commitment. You can also offer to help fund a port as project owners may be available for hire or some other developer may be available to do the port for you if you like the time.

What you can do TODAY even if you are blocked

No matter the status of your dependencies, you can start writing code that is compatible with Python 2 and 3 starting today. You can read Lennart Regebro's book or the porting HOWTO to see exactly what it entails for code to run under both Python 2 and 3 without modification (disclaimer: I wrote the foreword for Lennart's book when it was originally published). The hybrid language of Python 2/3 is surprisingly reasonable if you are coding for Python 2.6 or 2.7.

You can start using the hybrid Python for just new code. Then as you clean up code and fix it you can port it. And then finally you can begin to consider porting old code simply to port it. The point is that the sooner you start using the hybrid 2/3 version of Python in your code the faster and easier your eventual port to Python 3 will be.

Python 2.7 will still be here while you're blocked

And hopefully you view it as eventually instead of maybe (not). Python-dev continues to add features, improve performance, and fix bugs in Python 3 which continue to make it a fantastic programming language. We do realize that people's ability to port is eventual, though, which is why at PyCon 2014 Guido announced we are extending support for Python 2.7 until 2020 so you don't have horrible bugs causing you grief until you can port. But do realize that beyond critical security features, no new features will go into Python 2.7 so please don't ask for any. And regardless of what some t-shirts said at PyCon, there will be no Python 2.8. =)