2016 – the year of Python 3

Given I’ve posted before on the issues with Python 2 and unicode, it’s worth noting that there is a simple solution – upgrade to Python 3.

The libraries have now finally reached a point where they are, by and large, dual stack compatible, or have unofficial forks to get you through (e.g. Fabric and Fabric3).

From experience of having done a few ports myself now (and getting comfortable with the changes in Python 3 – remembering to use next() instead .next() keeps tripping up my finger memory), a few tips to bear in mind:

  1. Go for Python 3.5 if at all possible (if you’re using Ubuntu as your base OS, that means 16.04. If you’re using Red Hat… good luck). Try and start aligning your base OS choice now – you don’t want to combine doing an OS upgrade and language upgrade if you can avoid it.
  2. Don’t make your code base compatible with both 2.x and 3.x unless you absolutely have to – this is a lot of overhead. Unless you’re a library maintainer, or you have a library shared between multiple pieces of code, just go for a clean switch.
  3. If you do have libraries that have to work on both – six is your friend. The code will not look pretty, but they’ve pretty much thought of and dealt with all the cross version issues you need to deal with.
  4. Get into good habits now. As you are going to be porting that 2.7 code at some point. Try and do things in a Python 3 way where possible, and use something like Pylint to tell you when you are not. e.g. exceptions are instances, not classes. Look at sprinkling some from __future__ into your Python 2 code to turn on Python 3 features and fix what breaks.
  5. 2to3 is a good starting point, but not perfect. You will need to review its output. In some cases it gets confused with relative imports (e.g. if you have a global module and a local one, it can try and rename the global reference – e.g. having a module named celery.py). Also, it’s overly conservative when dealing with the changes to dicts returning generators versus lists, and will try to co-erce every .keys() to list(.keys()) – you probably don’t need that list() call in there.
  6. Unit tests – you do have them, right?
  7. Be brave – you need to bite the bullet and do this. There’s never going to be a good time, so think of it as part of the next big refactoring you do.
Posted on November 21, 2016 at 11:24 pm by Carlos Corbacho · Permalink
In: Python