Skip to content

Commit

Permalink
Move utility functions over to compat
Browse files Browse the repository at this point in the history
This moves the py2/py3 specific code into two separate functions
in the compat module.

No other functional changes.  I also inlined the conversion of the
parsed qs dict back to unicode as nothing else currently needs that
function and doesn't need to be a public API for now.
  • Loading branch information
jamesls committed Apr 4, 2016
1 parent 234f616 commit 79180bd
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 29 deletions.
4 changes: 2 additions & 2 deletions boto/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import os
import posixpath

from boto.compat import urllib, encodebytes
from boto.compat import urllib, encodebytes, parse_qs_safe
from boto.auth_handler import AuthHandler
from boto.exception import BotoClientError

Expand Down Expand Up @@ -690,7 +690,7 @@ def mangle_path_and_params(self, req):
modified_req.params = copy_params

raw_qs = parsed_path.query
existing_qs = boto.utils.parse_qs_safe(
existing_qs = parse_qs_safe(
raw_qs,
keep_blank_values=True
)
Expand Down
22 changes: 22 additions & 0 deletions boto/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
long_type = int
from configparser import ConfigParser, NoOptionError, NoSectionError
unquote_str = unquote_plus
parse_qs_safe = parse_qs
else:
StandardError = StandardError
long_type = long
Expand All @@ -78,3 +79,24 @@ def unquote_str(value, encoding='utf-8'):
# unquote it.
byte_string = value.encode(encoding)
return unquote_plus(byte_string).decode(encoding)

# These are the same default arguments for python3's
# urllib.parse.parse_qs.
def parse_qs_safe(qs, keep_blank_values=False, strict_parsing=False,
encoding='utf-8', errors='replace'):
"""Parse a query handling unicode arguments properly in Python 2."""
is_text_type = isinstance(qs, six.text_type)
if is_text_type:
# URL encoding uses ASCII code points only.
qs = qs.encode('ascii')
qs_dict = parse_qs(qs, keep_blank_values, strict_parsing)
if is_text_type:
# Decode the parsed dictionary back to unicode.
result = {}
for (name, value) in qs_dict.items():
decoded_name = name.decode(encoding, errors)
decoded_value = [item.decode(encoding, errors)
for item in value]
result[decoded_name] = decoded_value
return result
return qs_dict
27 changes: 0 additions & 27 deletions boto/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,33 +104,6 @@ def unquote_v(nv):
return (nv[0], urllib.parse.unquote(nv[1]))


def parse_qs_safe(qs, keep_blank_values=False, strict_parsing=False,
encoding='utf-8', errors='replace'):
"""Parse a query handling unicode arguments properly in Python 2."""
if six.PY3:
return urllib.parse.parse_qs(qs, keep_blank_values, strict_parsing,
encoding, errors)
else:
is_text_type = isinstance(qs, six.text_type)
if is_text_type:
qs = qs.encode('ascii') # URL encoding uses ASCII code points only

qs_dict = urllib.parse.parse_qs(qs, keep_blank_values, strict_parsing)

if is_text_type:
return decode_qs_dict(qs_dict, encoding, errors)
return qs_dict


def decode_qs_dict(qs_dict, encoding='utf-8', errors='replace'):
result = {}
for (name, value) in qs_dict.items():
decoded_name = name.decode(encoding, errors)
decoded_value = [item.decode(encoding, errors) for item in value]
result[decoded_name] = decoded_value
return result


def canonical_string(method, path, headers, expires=None,
provider=None):
"""
Expand Down

0 comments on commit 79180bd

Please sign in to comment.