Skip to content

Conversation

jmibanez
Copy link

@jmibanez jmibanez commented Aug 6, 2014

Various fixes to allow running on Python 3 as well as Python 2.

We use this to shim up some of the modules that changed locations between Python 2 and Python 3.
Breakage warning: this won't work on Python versions < 2.6.
To allow Python 3 compatibility, Django 1.5 renamed smart_unicode in django.utils.encoding as smart_text (as Python 3's str type is unicode by default). To accomodate running on earlier Django versions, we do an import of the old name; if we fail, we import smart_text as smart_unicode instead (with the assumption that Django is actually in the path).
urlparse in Python 3 has been subsumed into urllib; to support both Python 2 and Python 3, we import urlparse via Six. This commit also fixes a bug in the tests. There is an incorrect assumption that parse_qs parses just the query string of a full URL, when given a full URL; it doesn't, and instead parse_qs assumes the caller passes in just the query string part of the URL. When given a full URL, the rest of the URL including the first attribute in the query string is assigned as the first key of the resulting dictionary returned by parse_qs. Because the 'code' key incidentally ends up being the second attribute in the query string, the test passes. However, because there was a change in the ordering of the query string, no 'code' key could be found when running in Python 3.
Because Python 3 is strict when it comes to byte strings vs. text strings, and because Python 3 does not do any automatic coercion between the two types, we need to be more explicit. In particular, when using response.content (which is in really a byte string), we need to convert it to a particular character encoding before treating it as a text string. We assume UTF-8 for the tests, which *will* break in other encodings, but since these are the tests, we don't mind assuming UTF-8. As well, because encode() in the str type in Python 3 no longer supports non-character encodings such as Base64, we need to use codecs to do the conversion. We also fix the assumption that shortuuid.uuid() returns a byte string (which it doesn't) when passing to hashlib.
This breaks in Python 3, as modifying a dictionary while iterating through its keys raises an exception, because dict.keys() now returns a view instead of a materialized list. We instead pull out the session keys as a list and iterate through that instead, which works for both Python 3 and Python 2 (although in Python 2 this creates an additional list).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant