Weblog

Experimental Python 3 support

A little bit of history

In May, Vinay Sajip published a fork proving that it was possible to support both Python 2 and 3 with a single codebase, and pass the entire test suite. This fork built upon earlier efforts by Martin von Löwis.

Shortly after, the core team decided to use six as a compatibility layer, rather than an ad-hoc library. The goal was not only to cover Django's needs, but also to choose a solution that would work for the ecosystem at large. Starting with Django 1.5, six will be bundled as django.utils.six, and thus available for all Django applications that use the same porting strategy as Django itself.

The first actual step towards Python 3 support was to remove the u prefixes of unicode strings and add the unicode_literals future import. This change was committed at the DjangoCon Europe sprints in July.

Then the biggest part of the work happened over the last few weeks, with hundreds of commits updating various parts of Django.

The core team focused on writing Python 3 code with Python 2 compatibility, rather than the opposite, in order to future-proof the code base. In order to avoid confusion, functions and classes whose name included string or unicode were renamed to bytes and text respectively. As a consequence, the port was significantly more invasive than Vinay Sajip's proof of concept.

On the bright side, since string encoding and decoding operations need to be correct under Python 3, several approximations were corrected during the porting effort. Even though the compatibility code adds some noise, the resulting code is cleaner in many places.

I'd like to thank all the community members and core developers who contributed to this huge project.

What's next?

Does this mean that Django is ready to use with Python 3? Not yet!

First, Django has received next to none real-life testing under Python 3. Consider the code pre-alpha.

Then, while the core team did its best to eliminate bugs, the test suite doesn't cover all possible uses of Django. That's where the community comes in.

We need your help to test the development version of Django, not only to report bugs on Python 3, but also regressions on Python 2. While Django is very conservative with regards to backwards compatibility, mistakes are always possible, and it's likely that the massive refactoring work introduced some regressions.

Finally, Django is much more than a web framework — it's an ecosystem of pluggable applications. At this point, few third-party applications support Python 3. Authors are strongly encouraged to port their pluggable applications as soon as possible. Porting tips are available in the documentation.

Posted by Aymeric Augustin on August 19, 2012