From 79180bdc8349140e678c1971a04f58ba644bd672 Mon Sep 17 00:00:00 2001 From: James Saryerwinnie Date: Mon, 4 Apr 2016 13:41:20 -0700 Subject: [PATCH] Move utility functions over to compat 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. --- boto/auth.py | 4 ++-- boto/compat.py | 22 ++++++++++++++++++++++ boto/utils.py | 27 --------------------------- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/boto/auth.py b/boto/auth.py index 22cecf01c9..36df72276e 100644 --- a/boto/auth.py +++ b/boto/auth.py @@ -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 @@ -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 ) diff --git a/boto/compat.py b/boto/compat.py index 4cf24bc85b..d257180307 100644 --- a/boto/compat.py +++ b/boto/compat.py @@ -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 @@ -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 diff --git a/boto/utils.py b/boto/utils.py index 31fc9b5e8e..39a8cf77aa 100644 --- a/boto/utils.py +++ b/boto/utils.py @@ -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): """