Hopefully the 10th time's a charm on this one.
This patch attempts to solve the Python 2 / Python 3 incompatibilities by introducing a new encoded_file abstraction that we use instead of io.open(). The problem with the builtin implementation of io.open is that read and write accept and return unicode objects, which are not always convenient to work with in Python 2. We solve this by making encoded_file.open() return the same object returned by io.open() but with hooked read() and write() methods. These hooked methods will accept binary or text data, and conditionally convert what it gets to a unicode object using the correct encoding. When calling read() it also does any conversion necessary to convert the output back into the native string type of the running python version.
I actually tested this one on both Windows and Linux and it works fine. So hopefully this is closer to a working solution!