Using io.open(), which is the Python 3 open() in 2.6 and above.
Save notebook as script using unicode file handle.
Specify UTF-8 encoding for saving notebook as script.
A few other places we probably need to track this down:
Actually, this should be fixed at a lower level. json.dumps, which is used by the other writes returns str. The writes method for python scripts should also return str by using py3compat.unicode_to_str so the two (and all future) writes methods match in their return type.
Actually, I think this way is better than unicode_to_str. On Python 3, that will be a no-op, and it will be encoded by the text-mode file handle, which has a platform dependent default encoding (docs). But we hardcode the encoding comment to utf-8, so we should ensure that we're always encoding with utf-8.
The alternative would be to open a binary-mode file handle and encode it ourselves, but that lacks elegance. Conceptually, Python code is text, so it makes sense to write text.
There are probably other places that would benefit from using io.open - I wasn't aware of it when I wrote py3compat.
That's a fair point, but we should ensure that both the writes methods do return the same type, which is the real bug here. One or the other should change.
I am fine with this approach - let's just make sure the other calls to open in the notebook writing code get updated as well.