11import platform
22import sys
3+ import textwrap
4+
5+ import six
6+
7+ __all__ = [
8+ 'httplib' ,
9+ 'iteritems' ,
10+ 'PY2' ,
11+ 'Queue' ,
12+ 'stringify' ,
13+ 'StringIO' ,
14+ 'urlencode' ,
15+ 'parse' ,
16+ 'reraise' ,
17+ ]
318
419PYTHON_VERSION_INFO = sys .version_info
520PY2 = sys .version_info [0 ] == 2
823PYTHON_VERSION = platform .python_version ()
924PYTHON_INTERPRETER = platform .python_implementation ()
1025
11- stringify = str
12-
13- if PY2 :
14- from urllib import urlencode
15- import httplib
16- stringify = unicode
17- from Queue import Queue
18- try :
19- from cStringIO import StringIO
20- except ImportError :
21- from StringIO import StringIO
22- else :
23- from queue import Queue
24- from urllib .parse import urlencode
25- import http .client as httplib
26- from io import StringIO
27-
2826try :
29- import urlparse as parse
27+ StringIO = six . moves . cStringIO
3028except ImportError :
31- from urllib import parse
29+ StringIO = six . StringIO
3230
33- try :
31+ httplib = six .moves .http_client
32+ urlencode = six .moves .urllib .parse .urlencode
33+ parse = six .moves .urllib .parse
34+ Queue = six .moves .queue .Queue
35+ iteritems = six .iteritems
36+ reraise = six .reraise
37+
38+ stringify = six .text_type
39+ string_type = six .string_types [0 ]
40+ msgpack_type = six .binary_type
41+ # DEV: `six` doesn't have `float` in `integer_types`
42+ numeric_types = six .integer_types + (float , )
43+
44+
45+ if PYTHON_VERSION_INFO [0 :2 ] >= (3 , 4 ):
3446 from asyncio import iscoroutinefunction
35- from .compat_async import _make_async_decorator as make_async_decorator
36- except ImportError :
47+
48+ # Execute from a string to get around syntax errors from `yield from`
49+ # DEV: The idea to do this was stolen from `six`
50+ # https://github.com/benjaminp/six/blob/15e31431af97e5e64b80af0a3f598d382bcdd49a/six.py#L719-L737
51+ six .exec_ (textwrap .dedent ("""
52+ import functools
53+ import asyncio
54+
55+
56+ def make_async_decorator(tracer, coro, *params, **kw_params):
57+ \" \" \"
58+ Decorator factory that creates an asynchronous wrapper that yields
59+ a coroutine result. This factory is required to handle Python 2
60+ compatibilities.
61+
62+ :param object tracer: the tracer instance that is used
63+ :param function f: the coroutine that must be executed
64+ :param tuple params: arguments given to the Tracer.trace()
65+ :param dict kw_params: keyword arguments given to the Tracer.trace()
66+ \" \" \"
67+ @functools.wraps(coro)
68+ @asyncio.coroutine
69+ def func_wrapper(*args, **kwargs):
70+ with tracer.trace(*params, **kw_params):
71+ result = yield from coro(*args, **kwargs) # noqa: E999
72+ return result
73+
74+ return func_wrapper
75+ """ ))
76+
77+ else :
3778 # asyncio is missing so we can't have coroutines; these
3879 # functions are used only to ensure code executions in case
3980 # of an unexpected behavior
@@ -44,30 +85,24 @@ def make_async_decorator(tracer, fn, *params, **kw_params):
4485 return fn
4586
4687
47- def iteritems (obj , ** kwargs ):
48- func = getattr (obj , "iteritems" , None )
49- if not func :
50- func = obj .items
51- return func (** kwargs )
52-
53-
88+ # DEV: There is `six.u()` which does something similar, but doesn't have the guard around `hasattr(s, 'decode')`
5489def to_unicode (s ):
5590 """ Return a unicode string for the given bytes or string instance. """
5691 # No reason to decode if we already have the unicode compatible object we expect
57- # DEV: `stringify ` will be a `str` for python 3 and `unicode` for python 2
92+ # DEV: `six.text_type ` will be a `str` for python 3 and `unicode` for python 2
5893 # DEV: Double decoding a `unicode` can cause a `UnicodeEncodeError`
5994 # e.g. `'\xc3\xbf'.decode('utf-8').decode('utf-8')`
60- if isinstance (s , stringify ):
95+ if isinstance (s , six . text_type ):
6196 return s
6297
6398 # If the object has a `decode` method, then decode into `utf-8`
6499 # e.g. Python 2 `str`, Python 2/3 `bytearray`, etc
65100 if hasattr (s , 'decode' ):
66101 return s .decode ('utf-8' )
67102
68- # Always try to coerce the object into the `stringify ` object we expect
103+ # Always try to coerce the object into the `six.text_type ` object we expect
69104 # e.g. `to_unicode(1)`, `to_unicode(dict(key='value'))`
70- return stringify (s )
105+ return six . text_type (s )
71106
72107
73108def get_connection_response (conn ):
@@ -86,45 +121,3 @@ def get_connection_response(conn):
86121 return conn .getresponse (buffering = True )
87122 else :
88123 return conn .getresponse ()
89-
90-
91- if PY2 :
92- string_type = basestring
93- msgpack_type = basestring
94- numeric_types = (int , long , float )
95- else :
96- string_type = str
97- msgpack_type = bytes
98- numeric_types = (int , float )
99-
100- if PY2 :
101- # avoids Python 3 `SyntaxError`
102- # this block will be replaced with the `six` library
103- from .utils .reraise import _reraise as reraise
104- else :
105- def reraise (tp , value , tb = None ):
106- """Python 3 re-raise function. This function is internal and
107- will be replaced entirely with the `six` library.
108- """
109- try :
110- if value is None :
111- value = tp ()
112- if value .__traceback__ is not tb :
113- raise value .with_traceback (tb )
114- raise value
115- finally :
116- value = None
117- tb = None
118-
119-
120- __all__ = [
121- 'httplib' ,
122- 'iteritems' ,
123- 'PY2' ,
124- 'Queue' ,
125- 'stringify' ,
126- 'StringIO' ,
127- 'urlencode' ,
128- 'parse' ,
129- 'reraise' ,
130- ]
0 commit comments