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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant