Something we've done in MAAS — which is Python 2 only so far — is to put:
from __future__ import ( absolute_import, print_function, unicode_literals, ) __metaclass__ = type str = None
at the top of every source file. We knew that we would port MAAS to Python 3 at some point, and we hoped that doing this would help that effort. We'll find out if that's the case soon enough: one of our goals for this cycle is to port MAAS to Python 3.
str = None line forces us to use the
bytes synonym, and thus think more about what we're actually doing, but it doesn't save us from implicit conversions.
In places like data ingress and egress points we also assert unicode or byte strings, as appropriate, to try and catch ourselves slipping up. We also encode and decode at these points, with the goal of using only unicode strings internally for textual data.
We never coerce between unicode and byte strings either, because that involves implicit recoding; we always encode or decode explicitly.
In maas-test — which is a newer and smaller codebase than MAAS — we drop the
str = None line, but use tox to test on both Python 2.7 and 3.3. Unfortunately we've recently had to use a Python-2-only dependency and have had to disable 3.3 tests until it's ported.
maas-test started the same as maas: a Python 2 codebase with the same prologue in every source file. It's anecdotal, but it turned out that few changes were needed to get it working with Python 3.3, and I think that's in part because of the hoops we forced ourselves to jump through. We used six to bridge some gaps (
text_type in a few places,
PY3 in setup.py too), but nothing invasive. My fingers are crossed that this experience is repeated with MAAS.