_compat.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. # flake8: noqa
  2. # This whole file is full of lint errors
  3. import codecs
  4. import sys
  5. import operator
  6. import functools
  7. import warnings
  8. try:
  9. import builtins
  10. except ImportError:
  11. import __builtin__ as builtins
  12. PY2 = sys.version_info[0] == 2
  13. WIN = sys.platform.startswith('win')
  14. _identity = lambda x: x
  15. if PY2:
  16. unichr = unichr
  17. text_type = unicode
  18. string_types = (str, unicode)
  19. integer_types = (int, long)
  20. iterkeys = lambda d, *args, **kwargs: d.iterkeys(*args, **kwargs)
  21. itervalues = lambda d, *args, **kwargs: d.itervalues(*args, **kwargs)
  22. iteritems = lambda d, *args, **kwargs: d.iteritems(*args, **kwargs)
  23. iterlists = lambda d, *args, **kwargs: d.iterlists(*args, **kwargs)
  24. iterlistvalues = lambda d, *args, **kwargs: d.iterlistvalues(*args, **kwargs)
  25. int_to_byte = chr
  26. iter_bytes = iter
  27. exec('def reraise(tp, value, tb=None):\n raise tp, value, tb')
  28. def fix_tuple_repr(obj):
  29. def __repr__(self):
  30. cls = self.__class__
  31. return '%s(%s)' % (cls.__name__, ', '.join(
  32. '%s=%r' % (field, self[index])
  33. for index, field in enumerate(cls._fields)
  34. ))
  35. obj.__repr__ = __repr__
  36. return obj
  37. def implements_iterator(cls):
  38. cls.next = cls.__next__
  39. del cls.__next__
  40. return cls
  41. def implements_to_string(cls):
  42. cls.__unicode__ = cls.__str__
  43. cls.__str__ = lambda x: x.__unicode__().encode('utf-8')
  44. return cls
  45. def native_string_result(func):
  46. def wrapper(*args, **kwargs):
  47. return func(*args, **kwargs).encode('utf-8')
  48. return functools.update_wrapper(wrapper, func)
  49. def implements_bool(cls):
  50. cls.__nonzero__ = cls.__bool__
  51. del cls.__bool__
  52. return cls
  53. from itertools import imap, izip, ifilter
  54. range_type = xrange
  55. from StringIO import StringIO
  56. from cStringIO import StringIO as BytesIO
  57. NativeStringIO = BytesIO
  58. def make_literal_wrapper(reference):
  59. return _identity
  60. def normalize_string_tuple(tup):
  61. """Normalizes a string tuple to a common type. Following Python 2
  62. rules, upgrades to unicode are implicit.
  63. """
  64. if any(isinstance(x, text_type) for x in tup):
  65. return tuple(to_unicode(x) for x in tup)
  66. return tup
  67. def try_coerce_native(s):
  68. """Try to coerce a unicode string to native if possible. Otherwise,
  69. leave it as unicode.
  70. """
  71. try:
  72. return to_native(s)
  73. except UnicodeError:
  74. return s
  75. wsgi_get_bytes = _identity
  76. def wsgi_decoding_dance(s, charset='utf-8', errors='replace'):
  77. return s.decode(charset, errors)
  78. def wsgi_encoding_dance(s, charset='utf-8', errors='replace'):
  79. if isinstance(s, bytes):
  80. return s
  81. return s.encode(charset, errors)
  82. def to_bytes(x, charset=sys.getdefaultencoding(), errors='strict'):
  83. if x is None:
  84. return None
  85. if isinstance(x, (bytes, bytearray, buffer)):
  86. return bytes(x)
  87. if isinstance(x, unicode):
  88. return x.encode(charset, errors)
  89. raise TypeError('Expected bytes')
  90. def to_native(x, charset=sys.getdefaultencoding(), errors='strict'):
  91. if x is None or isinstance(x, str):
  92. return x
  93. return x.encode(charset, errors)
  94. else:
  95. unichr = chr
  96. text_type = str
  97. string_types = (str, )
  98. integer_types = (int, )
  99. iterkeys = lambda d, *args, **kwargs: iter(d.keys(*args, **kwargs))
  100. itervalues = lambda d, *args, **kwargs: iter(d.values(*args, **kwargs))
  101. iteritems = lambda d, *args, **kwargs: iter(d.items(*args, **kwargs))
  102. iterlists = lambda d, *args, **kwargs: iter(d.lists(*args, **kwargs))
  103. iterlistvalues = lambda d, *args, **kwargs: iter(d.listvalues(*args, **kwargs))
  104. int_to_byte = operator.methodcaller('to_bytes', 1, 'big')
  105. iter_bytes = functools.partial(map, int_to_byte)
  106. def reraise(tp, value, tb=None):
  107. if value.__traceback__ is not tb:
  108. raise value.with_traceback(tb)
  109. raise value
  110. fix_tuple_repr = _identity
  111. implements_iterator = _identity
  112. implements_to_string = _identity
  113. implements_bool = _identity
  114. native_string_result = _identity
  115. imap = map
  116. izip = zip
  117. ifilter = filter
  118. range_type = range
  119. from io import StringIO, BytesIO
  120. NativeStringIO = StringIO
  121. _latin1_encode = operator.methodcaller('encode', 'latin1')
  122. def make_literal_wrapper(reference):
  123. if isinstance(reference, text_type):
  124. return _identity
  125. return _latin1_encode
  126. def normalize_string_tuple(tup):
  127. """Ensures that all types in the tuple are either strings
  128. or bytes.
  129. """
  130. tupiter = iter(tup)
  131. is_text = isinstance(next(tupiter, None), text_type)
  132. for arg in tupiter:
  133. if isinstance(arg, text_type) != is_text:
  134. raise TypeError('Cannot mix str and bytes arguments (got %s)'
  135. % repr(tup))
  136. return tup
  137. try_coerce_native = _identity
  138. wsgi_get_bytes = _latin1_encode
  139. def wsgi_decoding_dance(s, charset='utf-8', errors='replace'):
  140. return s.encode('latin1').decode(charset, errors)
  141. def wsgi_encoding_dance(s, charset='utf-8', errors='replace'):
  142. if isinstance(s, text_type):
  143. s = s.encode(charset)
  144. return s.decode('latin1', errors)
  145. def to_bytes(x, charset=sys.getdefaultencoding(), errors='strict'):
  146. if x is None:
  147. return None
  148. if isinstance(x, (bytes, bytearray, memoryview)): # noqa
  149. return bytes(x)
  150. if isinstance(x, str):
  151. return x.encode(charset, errors)
  152. raise TypeError('Expected bytes')
  153. def to_native(x, charset=sys.getdefaultencoding(), errors='strict'):
  154. if x is None or isinstance(x, str):
  155. return x
  156. return x.decode(charset, errors)
  157. def to_unicode(x, charset=sys.getdefaultencoding(), errors='strict',
  158. allow_none_charset=False):
  159. if x is None:
  160. return None
  161. if not isinstance(x, bytes):
  162. return text_type(x)
  163. if charset is None and allow_none_charset:
  164. return x
  165. return x.decode(charset, errors)