SoCo/SoCo — pull request #42 by doreilly (2013-10-21 01:39:58+00:00)
Title: Make Python3 compatible.

SoCo doesn't declare any version requirements. Looking at the code, it was clear that it was at most Python 2.7 (but probably 2.6 or greater) but not Python 3 compatible. I have some ideas for using SoCo, however I am aiming to use Python 3.3 or later. The basic changes involved in getting SoCo to run under py3k were very minimal since much of the code is fairly clean with respect to forward compatibility (thanks to efforts such as #36), but the method is perhaps worth discussion before merging the code.

The unit tests pass on my OS X machine running Python 2.7.2 and Python 3.3.2.

I considered using [six](http://pythonhosted.org/six/) to do some of the work, but the code changes were so minimal, that it didn't seem worth the additional library requirement.

The method I chose for cross-compatibility was:

1. enable `unicode_literals` (requires Python 2.6 or greater), and prefix any necessary bytestrings with `b`.
2. ensure wire-level strings are byte strings (`str` in Python 2, `bytes` in Python 3), and incoming text is converted to text strings as soon as possible (`unicode` in Python 2, `str` in Python 3).
3. enable `print_function` as required (also requires Python 2.6 or greater).
4. Modify/replace any imports that have moved/no longer exist in python 3.

Item number 1 above is probably the most dangerous part of the process, as any un-prefixed string literal in the module instantly becomes a `unicode` object in Python 2. This could cause some encoding/decoding errors in python 2, though none appear to be evident.

Item number 2 really only affected a few small parts of the code. The major change is using `requests.Response.text` rather than `requests.Response.content` for the return value of `SoCo.__send_command()` Requests mostly takes care of the hard work of determining the response encoding and decoding the bytes appropriately.

Item number 3 is trivial and does not impact `core.py`

Item number 4 is fairly trivial as well. In Python 3, the types module lost the StringType and UnicodeType names, so they are aliased to `bytes` and `str` as necessary.