Porting to Python 3 is like "eating your vegetables"

While at PyCon this year, someone pointed out that the hope/goal/expectation when Python 3 was released was to have over 50% of new projects using Python 3 within five years, and that had not come to fruition (while I have not personally crunched the numbers and this was told to me anecdotally, I will just assume they are right). Immediately after pointing this out they said that Python 3 is thus a failure at this point and we need to start figuring out when we call it quits on Python 3. I obviously disagree with this view.

We can't predict the future

Just because some prediction didn't come true does not mean we have lost hope in Python 3. All it means is that the community's uptake of Python 3 has been slower than we initially thought, and honestly that's fine. The extension of Python 2.7's end-of-life to 2020 is an acknowledgment of this slower pace. There are plenty of companies and projects which have switched to Python 3 fully or are at least supporting it and seem happy with Python 3. The polling of the audience by Guido during his keynote along with some uptake numbers shared in confidence with the core developers shows that the level of use is actually too high to consider abandoning Python 3 without screwing over a sizable chunk of the community (Donald Stufft's post on PyPI download statistics shows this).

So why are we as a community, more than 6 years after Python 3 was released, not transitioning to Python 3 faster? At the language summit, Larry Hastings said porting to Python 3 is like "eating your vegetables"; you know you should, but that doesn't make it enjoyable. I think that is a very fair analogy as to why most people don't finding porting fun.

Why the hell we separated text and binary data in the language

I have a sneaking suspicion that some people think we decided to clearly separate text and binary data "just because" or it seemed like the proper thing to do from some theoretical language design standpoint or something; all of those reasons are wrong. The reason we made the separation was to provide language level support/restrictions to prevent people from making subtle bugs when they mixed text and binary data. Talk to a Django core developer and ask them how much code and work it is to properly handle the separation of text and binary data in Python 2 and I'm sure you will be told it's a lot and it's a pain. I think Jacob Kaplan-Moss tells me almost annually at PyCon that the day Django stops supporting Python 2 they will be able to rip out a ton of code that exists purely because it was so easy to mix text and binary data and get it wrong. In other words most of us are mediocre programmers and this text/binary separation helps us not to screw up (also making sure code works with Unicode for text is also a benefit of this separation).

This means dealing with the text/binary separation in Python 3 is part of eating your vegetables. It was done to help people in the long term. People also seem to forget that the core developers have to eat the exact same vegetables as everyone else. The core developers are not some magical group of people who get to code in Python 3 all day long; plenty of us core developers still work with Python 2 as part of our job. That means decisions like the text/binary separation are not taken lightly as it impacts our lives just like everyone else's.

How to make eating your vegetables easier

So you should eat your vegetables, but that doesn't mean we can't try to make it easier. I gave a talk at PyCon 2015 on making Python 2 code be 2/3 compatible. You should be able to get all the same information from the Python 2/3 porting HOWTO. The tooling and such should actually be to the point that if you run your code against Python 2.7 and Python 3.5 (when it's released) that any porting issue shouldn't be silent but instead raise a warning, exception, message, etc. In other words the only bit that should require a good amount of thinking is the text/binary separation for your APIs and making that separation happen.

You can also view the various steps to support Python 3 as part of your code's health if that helps motivate you (or your manager). Since the changes in Python 3 are to make your code better, you could argue that modernizing your code and cleaning it up in Python 2 has a side-effect of supporting Python 3. And much like code maintenance, you can make porting a piecemeal process where you don't have to do all of it at once but in pieces to gain different things (e.g., moving to iterator versions of map and other built-ins can lead to better performance and more use of iterators which just happens to align with what Python 3's built-ins do).

But please don't assume porting is free. It can be fairly straightforward for some projects, but harder for others. Either way there is some work involved. There have been reports of people in the community being somewhat mean to project maintainers for not porting which isn't right. You can always ask someone to port their code, but you should always be cordial about it and be understanding if they choose not to.

Getting treats for eating your vegetables

Like many of you, when I was younger and I didn't want to eat my vegetables my parents would tell me that if I did eat my vegetables I would get dessert. The Python development team is constantly trying to toss in more desserts into Python 3.

For some it may be asyncio that they get to look forward to when they port (and I'm willing to bet the first person to create a library which really harnesses asyncio is going to have a popular project on their hands). Others may be looking forward to type hints inlined in their code (for Python 2 you can put the type hints in stub files). Assuming things go the way I think they will, the async/await syntax for co-routines will be landing in Python 3.5 and that seems to be exciting people. For others it might be performance improvements that we have landed over the years which help with things like memory usage from strings, etc. But the point is that we are always trying to make your effort in porting to Python 3 worth that much more.

We are one community

Regardless of what version of Python you run, we are still a single community. While I think Python 3.4 is currently the best version of Python available, you're welcome to disagree with me or agree but not think it's worth your time and effort to use it; all I ask is you be informed in your opinion. Honestly, if some people never switch to Python 3 and make Python 2 the COBOL of dynamic programming languages I'm totally fine with it (just as long as you don't make me maintain it past 2020 ☺). The one thing I really want to make sure never goes away is how awesome the Python community is.