five.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. # -*- coding: utf-8 -*-
  2. """
  3. celery.five
  4. ~~~~~~~~~~~
  5. Compatibility implementations of features
  6. only available in newer Python versions.
  7. """
  8. from __future__ import absolute_import
  9. # ############# py3k #########################################################
  10. import sys
  11. PY3 = sys.version_info[0] == 3
  12. try:
  13. reload = reload # noqa
  14. except NameError: # pragma: no cover
  15. try:
  16. from importlib import reload # noqa
  17. except ImportError: # pragma: no cover
  18. from imp import reload # noqa
  19. try:
  20. from UserList import UserList # noqa
  21. except ImportError: # pragma: no cover
  22. from collections import UserList # noqa
  23. try:
  24. from UserDict import UserDict # noqa
  25. except ImportError: # pragma: no cover
  26. from collections import UserDict # noqa
  27. # ############# time.monotonic ###############################################
  28. if sys.version_info < (3, 3):
  29. import platform
  30. SYSTEM = platform.system()
  31. try:
  32. import ctypes
  33. except ImportError: # pragma: no cover
  34. ctypes = None # noqa
  35. if SYSTEM == 'Darwin' and ctypes is not None:
  36. from ctypes.util import find_library
  37. libSystem = ctypes.CDLL(find_library('libSystem.dylib'))
  38. CoreServices = ctypes.CDLL(find_library('CoreServices'),
  39. use_errno=True)
  40. mach_absolute_time = libSystem.mach_absolute_time
  41. mach_absolute_time.restype = ctypes.c_uint64
  42. absolute_to_nanoseconds = CoreServices.AbsoluteToNanoseconds
  43. absolute_to_nanoseconds.restype = ctypes.c_uint64
  44. absolute_to_nanoseconds.argtypes = [ctypes.c_uint64]
  45. def _monotonic():
  46. return absolute_to_nanoseconds(mach_absolute_time()) * 1e-9
  47. elif SYSTEM == 'Linux' and ctypes is not None:
  48. # from stackoverflow:
  49. # questions/1205722/how-do-i-get-monotonic-time-durations-in-python
  50. import ctypes
  51. import os
  52. CLOCK_MONOTONIC = 1 # see <linux/time.h>
  53. class timespec(ctypes.Structure):
  54. _fields_ = [
  55. ('tv_sec', ctypes.c_long),
  56. ('tv_nsec', ctypes.c_long),
  57. ]
  58. librt = ctypes.CDLL('librt.so.1', use_errno=True)
  59. clock_gettime = librt.clock_gettime
  60. clock_gettime.argtypes = [
  61. ctypes.c_int, ctypes.POINTER(timespec),
  62. ]
  63. def _monotonic(): # noqa
  64. t = timespec()
  65. if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(t)) != 0:
  66. errno_ = ctypes.get_errno()
  67. raise OSError(errno_, os.strerror(errno_))
  68. return t.tv_sec + t.tv_nsec * 1e-9
  69. else:
  70. from time import time as _monotonic
  71. try:
  72. from time import monotonic
  73. except ImportError:
  74. monotonic = _monotonic # noqa
  75. if PY3:
  76. import builtins
  77. from queue import Queue, Empty, Full
  78. from itertools import zip_longest
  79. from io import StringIO, BytesIO
  80. map = map
  81. string = str
  82. string_t = str
  83. long_t = int
  84. text_t = str
  85. range = range
  86. int_types = (int, )
  87. def items(d):
  88. return d.items()
  89. def keys(d):
  90. return d.keys()
  91. def values(d):
  92. return d.values()
  93. def nextfun(it):
  94. return it.__next__
  95. exec_ = getattr(builtins, 'exec')
  96. def reraise(tp, value, tb=None):
  97. if value.__traceback__ is not tb:
  98. raise value.with_traceback(tb)
  99. raise value
  100. class WhateverIO(StringIO):
  101. def write(self, data):
  102. if isinstance(data, bytes):
  103. data = data.encode()
  104. StringIO.write(self, data)
  105. else:
  106. import __builtin__ as builtins # noqa
  107. from Queue import Queue, Empty, Full # noqa
  108. from itertools import imap as map, izip_longest as zip_longest # noqa
  109. from StringIO import StringIO # noqa
  110. string = unicode # noqa
  111. string_t = basestring # noqa
  112. text_t = unicode
  113. long_t = long # noqa
  114. range = xrange
  115. int_types = (int, long)
  116. def items(d): # noqa
  117. return d.iteritems()
  118. def keys(d): # noqa
  119. return d.iterkeys()
  120. def values(d): # noqa
  121. return d.itervalues()
  122. def nextfun(it): # noqa
  123. return it.next
  124. def exec_(code, globs=None, locs=None):
  125. """Execute code in a namespace."""
  126. if globs is None:
  127. frame = sys._getframe(1)
  128. globs = frame.f_globals
  129. if locs is None:
  130. locs = frame.f_locals
  131. del frame
  132. elif locs is None:
  133. locs = globs
  134. exec("""exec code in globs, locs""")
  135. exec_("""def reraise(tp, value, tb=None): raise tp, value, tb""")
  136. BytesIO = WhateverIO = StringIO # noqa
  137. def with_metaclass(Type, skip_attrs=set(['__dict__', '__weakref__'])):
  138. """Class decorator to set metaclass.
  139. Works with both Python 2 and Python 3 and it does not add
  140. an extra class in the lookup order like ``six.with_metaclass`` does
  141. (that is -- it copies the original class instead of using inheritance).
  142. """
  143. def _clone_with_metaclass(Class):
  144. attrs = dict((key, value) for key, value in items(vars(Class))
  145. if key not in skip_attrs)
  146. return Type(Class.__name__, Class.__bases__, attrs)
  147. return _clone_with_metaclass