_compat.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. # -*- coding: utf-8 -*-
  2. """
  3. jinja2._compat
  4. ~~~~~~~~~~~~~~
  5. Some py2/py3 compatibility support based on a stripped down
  6. version of six so we don't have to depend on a specific version
  7. of it.
  8. :copyright: Copyright 2013 by the Jinja team, see AUTHORS.
  9. :license: BSD, see LICENSE for details.
  10. """
  11. import sys
  12. PY2 = sys.version_info[0] == 2
  13. PYPY = hasattr(sys, 'pypy_translation_info')
  14. _identity = lambda x: x
  15. if not PY2:
  16. unichr = chr
  17. range_type = range
  18. text_type = str
  19. string_types = (str,)
  20. iterkeys = lambda d: iter(d.keys())
  21. itervalues = lambda d: iter(d.values())
  22. iteritems = lambda d: iter(d.items())
  23. import pickle
  24. from io import BytesIO, StringIO
  25. NativeStringIO = StringIO
  26. def reraise(tp, value, tb=None):
  27. if value.__traceback__ is not tb:
  28. raise value.with_traceback(tb)
  29. raise value
  30. ifilter = filter
  31. imap = map
  32. izip = zip
  33. intern = sys.intern
  34. implements_iterator = _identity
  35. implements_to_string = _identity
  36. encode_filename = _identity
  37. get_next = lambda x: x.__next__
  38. else:
  39. unichr = unichr
  40. text_type = unicode
  41. range_type = xrange
  42. string_types = (str, unicode)
  43. iterkeys = lambda d: d.iterkeys()
  44. itervalues = lambda d: d.itervalues()
  45. iteritems = lambda d: d.iteritems()
  46. import cPickle as pickle
  47. from cStringIO import StringIO as BytesIO, StringIO
  48. NativeStringIO = BytesIO
  49. exec('def reraise(tp, value, tb=None):\n raise tp, value, tb')
  50. from itertools import imap, izip, ifilter
  51. intern = intern
  52. def implements_iterator(cls):
  53. cls.next = cls.__next__
  54. del cls.__next__
  55. return cls
  56. def implements_to_string(cls):
  57. cls.__unicode__ = cls.__str__
  58. cls.__str__ = lambda x: x.__unicode__().encode('utf-8')
  59. return cls
  60. get_next = lambda x: x.next
  61. def encode_filename(filename):
  62. if isinstance(filename, unicode):
  63. return filename.encode('utf-8')
  64. return filename
  65. try:
  66. next = next
  67. except NameError:
  68. def next(it):
  69. return it.next()
  70. def with_metaclass(meta, *bases):
  71. # This requires a bit of explanation: the basic idea is to make a
  72. # dummy metaclass for one level of class instanciation that replaces
  73. # itself with the actual metaclass. Because of internal type checks
  74. # we also need to make sure that we downgrade the custom metaclass
  75. # for one level to something closer to type (that's why __call__ and
  76. # __init__ comes back from type etc.).
  77. #
  78. # This has the advantage over six.with_metaclass in that it does not
  79. # introduce dummy classes into the final MRO.
  80. class metaclass(meta):
  81. __call__ = type.__call__
  82. __init__ = type.__init__
  83. def __new__(cls, name, this_bases, d):
  84. if this_bases is None:
  85. return type.__new__(cls, name, (), d)
  86. return meta(name, bases, d)
  87. return metaclass('temporary_class', None, {})
  88. try:
  89. from collections import Mapping as mapping_types
  90. except ImportError:
  91. import UserDict
  92. mapping_types = (UserDict.UserDict, UserDict.DictMixin, dict)
  93. # common types. These do exist in the special types module too which however
  94. # does not exist in IronPython out of the box. Also that way we don't have
  95. # to deal with implementation specific stuff here
  96. class _C(object):
  97. def method(self): pass
  98. def _func():
  99. yield None
  100. function_type = type(_func)
  101. generator_type = type(_func())
  102. method_type = type(_C().method)
  103. code_type = type(_C.method.__code__)
  104. try:
  105. raise TypeError()
  106. except TypeError:
  107. _tb = sys.exc_info()[2]
  108. traceback_type = type(_tb)
  109. frame_type = type(_tb.tb_frame)
  110. try:
  111. from urllib.parse import quote_from_bytes as url_quote
  112. except ImportError:
  113. from urllib import quote as url_quote
  114. try:
  115. from thread import allocate_lock
  116. except ImportError:
  117. try:
  118. from threading import Lock as allocate_lock
  119. except ImportError:
  120. from dummy_thread import allocate_lock