_compat.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. # -*- coding: utf-8 -*-
  2. """
  3. flask_script._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: (c) 2013 by Armin Ronacher.
  9. :license: BSD, see LICENSE for more 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. integer_types = (int, )
  21. iterkeys = lambda d: iter(d.keys())
  22. itervalues = lambda d: iter(d.values())
  23. iteritems = lambda d: iter(d.items())
  24. import pickle
  25. from io import BytesIO, StringIO
  26. NativeStringIO = StringIO
  27. def reraise(tp, value, tb=None):
  28. if value.__traceback__ is not tb:
  29. raise value.with_traceback(tb)
  30. raise value
  31. ifilter = filter
  32. imap = map
  33. izip = zip
  34. intern = sys.intern
  35. implements_iterator = _identity
  36. implements_to_string = _identity
  37. encode_filename = _identity
  38. get_next = lambda x: x.__next__
  39. input = input
  40. from string import ascii_lowercase
  41. else:
  42. unichr = unichr
  43. text_type = unicode
  44. range_type = xrange
  45. string_types = (str, unicode)
  46. integer_types = (int, long)
  47. iterkeys = lambda d: d.iterkeys()
  48. itervalues = lambda d: d.itervalues()
  49. iteritems = lambda d: d.iteritems()
  50. import cPickle as pickle
  51. from cStringIO import StringIO as BytesIO, StringIO
  52. NativeStringIO = BytesIO
  53. exec('def reraise(tp, value, tb=None):\n raise tp, value, tb')
  54. from itertools import imap, izip, ifilter
  55. intern = intern
  56. def implements_iterator(cls):
  57. cls.next = cls.__next__
  58. del cls.__next__
  59. return cls
  60. def implements_to_string(cls):
  61. cls.__unicode__ = cls.__str__
  62. cls.__str__ = lambda x: x.__unicode__().encode('utf-8')
  63. return cls
  64. get_next = lambda x: x.next
  65. def encode_filename(filename):
  66. if isinstance(filename, unicode):
  67. return filename.encode('utf-8')
  68. return filename
  69. input = raw_input
  70. from string import lower as ascii_lowercase
  71. def with_metaclass(meta, *bases):
  72. # This requires a bit of explanation: the basic idea is to make a
  73. # dummy metaclass for one level of class instantiation that replaces
  74. # itself with the actual metaclass. Because of internal type checks
  75. # we also need to make sure that we downgrade the custom metaclass
  76. # for one level to something closer to type (that's why __call__ and
  77. # __init__ comes back from type etc.).
  78. #
  79. # This has the advantage over six.with_metaclass in that it does not
  80. # introduce dummy classes into the final MRO.
  81. class metaclass(meta):
  82. __call__ = type.__call__
  83. __init__ = type.__init__
  84. def __new__(cls, name, this_bases, d):
  85. if this_bases is None:
  86. return type.__new__(cls, name, (), d)
  87. return meta(name, bases, d)
  88. return metaclass('temporary_class', None, {})
  89. try:
  90. from urllib.parse import quote_from_bytes as url_quote
  91. except ImportError:
  92. from urllib import quote as url_quote