3030import binascii
3131import httplib2
3232
33+ from ._compat import PY3
34+ from ._compat import parse_qs
3335from ._compat import quote
3436from ._compat import STRING_TYPES
3537from ._compat import TEXT
3840from ._compat import urlencode
3941from ._compat import urlparse
4042from ._compat import urlunparse
41- from ._compat import parse_qs
4243from ._version import __version__
4344
4445OAUTH_VERSION = '1.0' # Hi Blaine!
@@ -154,7 +155,9 @@ def to_utf8_optional_iterator(x):
154155
155156def escape (s ):
156157 """Escape a URL including any /."""
157- return quote (s .encode ('utf-8' ), safe = '~' )
158+ if not isinstance (s , bytes ):
159+ s = s .encode ('utf-8' )
160+ return quote (s , safe = '~' )
158161
159162def generate_timestamp ():
160163 """Get seconds since epoch (UTC)."""
@@ -339,7 +342,7 @@ class Request(dict):
339342 version = OAUTH_VERSION
340343
341344 def __init__ (self , method = HTTP_METHOD , url = None , parameters = None ,
342- body = '' , is_form_encoded = False ):
345+ body = b '' , is_form_encoded = False ):
343346 if url is not None :
344347 self .url = to_unicode (url )
345348 self .method = method
@@ -555,7 +558,7 @@ def from_request(cls, http_method, http_url, headers=None, parameters=None,
555558 @classmethod
556559 def from_consumer_and_token (cls , consumer , token = None ,
557560 http_method = HTTP_METHOD , http_url = None , parameters = None ,
558- body = '' , is_form_encoded = False ):
561+ body = b '' , is_form_encoded = False ):
559562 if not parameters :
560563 parameters = {}
561564
@@ -611,7 +614,9 @@ def _split_header(header):
611614 @staticmethod
612615 def _split_url_string (param_str ):
613616 """Turn URL string into parameters."""
614- parameters = parse_qs (param_str .encode ('utf-8' ),
617+ #XXX parse_qs is leaving the encoded bytes after un-escaping
618+ #parameters = parse_qs(param_str.encode('utf-8'),
619+ parameters = parse_qs (param_str ,
615620 keep_blank_values = True )
616621 for k , v in parameters .items ():
617622 parameters [k ] = unquote_to_bytes (v [0 ])
@@ -643,7 +648,7 @@ def set_signature_method(self, method):
643648
644649 self .method = method
645650
646- def request (self , uri , method = "GET" , body = '' , headers = None ,
651+ def request (self , uri , method = "GET" , body = b '' , headers = None ,
647652 redirections = httplib2 .DEFAULT_MAX_REDIRECTS , connection_type = None ):
648653 DEFAULT_POST_CONTENT_TYPE = 'application/x-www-form-urlencoded'
649654
@@ -828,7 +833,7 @@ def signing_base(self, request, consumer, token):
828833 if token :
829834 key += escape (token .secret )
830835 raw = '&' .join (sig )
831- return key , raw
836+ return key . encode ( 'ascii' ) , raw . encode ( 'ascii' )
832837
833838 def sign (self , request , consumer , token ):
834839 """Builds the base signature string."""
@@ -854,4 +859,4 @@ def signing_base(self, request, consumer, token):
854859
855860 def sign (self , request , consumer , token ):
856861 key , raw = self .signing_base (request , consumer , token )
857- return raw
862+ return raw . encode ( 'utf8' )
0 commit comments