Porting an existing code base to Python 3 can seem like a huge and scary task, but there are things that can be done now, while you are still using Python 2.7, that can help alleviate the Python3 migration pain in the future. Python provides the 2to3 tool to automatically port existing code, but in my experience with it I found that I still had to do a fair bit of by-hand editing and I ended up with 2 sets of code, one for Python 2.7 and one for 3.2+, which just adds more difficulty.
Many of the Python 3 features have been back-ported to Python 2.7 in one way or another, so the best way to reduce porting pain in the future is to write code that is at least mostly compatible with both Python 2.7 and 3.2+ at the same time. It's not too hard to do with new modules and existing modules can usually be migrated over with a few minutes of work. In a nutshell, changing a few things in your coding style and practices now can make the future migration easier. Based on my experience my suggestions are:
- Use all the Py3 "from __future__ import ..." options. The one that had the biggest impact for my code was absolute_import
- Explicitly close() all files when done with them.
- Begin thinking of strings as being different types (unicode or bytes) based on their use, even if they really are the same str type currently. In other words, think of all text as unicode objects and all data as bytes objects, and write your code accordingly.
- Use bytes() instead of str() for converting to data. It's just an alias for str now but they will need to be changed for Py3 anyway. Continue to use str() for converting things that are meant to be readable text, not data.
- Use the six module (https://pypi.python.org/pypi/six) or something like it to help smooth out some of the other differences between Py2 and Py3. For example, instead of using "isinstance(obj, basestring)" you can use "isinstance(obj, six.string_types)". It also helps you deal with modules or classes that have changed names or locations in the standard library. Unfortunately it's hard to remember to actually use the things in six until you are using Py3 and are getting errors.
These practices, and a few others that will help write code that is compatible with both Python 2.7 and Python 3, are also discussed in this excellent summary in the Python documentation.