_compat.py 6.0 KB

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