This post is partially related to my previous blog post about Rewind.

I initially started the implementation of Rewind in Python 2.7. I constantly kept test coverage to 100%, and I tried to stick to TDD as much as possible. The Python testing tool Nose proved to be very valuable, as did Travis CI.

After some time I thought “Hey, why work in Python 2 when Python 3 seems around corner?”. I installed Python 3.2 on my laptop and started executing those tests. Travis CI helped a lot here to always make sure that Rewind was backward compatible with Python 2.7. Ever nervous about a test failing? Make pull request on Github and Travis CI will tell you whether the pull request broke something or not. Highly convenient. Migration to Python 3 can be summarized in three paragraphs:

Migrate from lists to iterators. In many ways I like the changes to the built-in functions map and reduce. Working with iterators are in many ways a higher abstraction. I did have some code that expected these functions to return lists. The flip side was that I sometimes had to wrap in list:

variable = list(map(func, someiter))

In hindsight, I probably should have used list comprehensions for many of those cases as they are more readable…

Use the ‘bytes’ type instead of ‘string’ where appropriate. bytes was introduced as a new type in Python 3. In the Rewind case, this mostly involved ZeroMQ message frames handling, that takes bytes. This also involved some conversion to and/or from bytes and string. I tried to stick to UTF-8 for this.

Use ‘string.format(…)’ instead of ‘string % …’ pattern. Nuff said.

Looking back Link to heading

In general, Python 3 is very backwards compatible (but Python 2 is not forward compatible). As far as I can recollect, the only conditionals I needed to make Python3 were aliasing of imports:

try:
    # Python < 3
    import ConfigParser as configparser
except ImportError:
    # Python >= 3
    import configparser