PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/vcs/utils/compat.py

https://bitbucket.org/marcinkuzminski/vcs/
Python | 318 lines | 255 code | 39 blank | 24 comment | 62 complexity | 277f9836597f14acef186826fb377ce9 MD5 | raw file
  1. """
  2. Various utilities to work with Python < 2.7.
  3. Those utilities may be deleted once ``vcs`` stops support for older Python
  4. versions.
  5. """
  6. import sys
  7. import array
  8. if sys.version_info >= (2, 7):
  9. unittest = __import__('unittest')
  10. else:
  11. unittest = __import__('unittest2')
  12. if sys.version_info >= (2, 6):
  13. _bytes = bytes
  14. else:
  15. # in py2.6 bytes is a synonim for str
  16. _bytes = str
  17. if sys.version_info >= (2, 6):
  18. _bytearray = bytearray
  19. else:
  20. # no idea if this is correct but all integration tests are passing
  21. # i think we never use bytearray anyway
  22. _bytearray = array
  23. if sys.version_info >= (2, 6):
  24. from collections import deque
  25. else:
  26. #need to implement our own deque with maxlen
  27. class deque(object):
  28. def __init__(self, iterable=(), maxlen= -1):
  29. if not hasattr(self, 'data'):
  30. self.left = self.right = 0
  31. self.data = {}
  32. self.maxlen = maxlen or -1
  33. self.extend(iterable)
  34. def append(self, x):
  35. self.data[self.right] = x
  36. self.right += 1
  37. if self.maxlen != -1 and len(self) > self.maxlen:
  38. self.popleft()
  39. def appendleft(self, x):
  40. self.left -= 1
  41. self.data[self.left] = x
  42. if self.maxlen != -1 and len(self) > self.maxlen:
  43. self.pop()
  44. def pop(self):
  45. if self.left == self.right:
  46. raise IndexError('cannot pop from empty deque')
  47. self.right -= 1
  48. elem = self.data[self.right]
  49. del self.data[self.right]
  50. return elem
  51. def popleft(self):
  52. if self.left == self.right:
  53. raise IndexError('cannot pop from empty deque')
  54. elem = self.data[self.left]
  55. del self.data[self.left]
  56. self.left += 1
  57. return elem
  58. def clear(self):
  59. self.data.clear()
  60. self.left = self.right = 0
  61. def extend(self, iterable):
  62. for elem in iterable:
  63. self.append(elem)
  64. def extendleft(self, iterable):
  65. for elem in iterable:
  66. self.appendleft(elem)
  67. def rotate(self, n=1):
  68. if self:
  69. n %= len(self)
  70. for i in xrange(n):
  71. self.appendleft(self.pop())
  72. def __getitem__(self, i):
  73. if i < 0:
  74. i += len(self)
  75. try:
  76. return self.data[i + self.left]
  77. except KeyError:
  78. raise IndexError
  79. def __setitem__(self, i, value):
  80. if i < 0:
  81. i += len(self)
  82. try:
  83. self.data[i + self.left] = value
  84. except KeyError:
  85. raise IndexError
  86. def __delitem__(self, i):
  87. size = len(self)
  88. if not (-size <= i < size):
  89. raise IndexError
  90. data = self.data
  91. if i < 0:
  92. i += size
  93. for j in xrange(self.left + i, self.right - 1):
  94. data[j] = data[j + 1]
  95. self.pop()
  96. def __len__(self):
  97. return self.right - self.left
  98. def __cmp__(self, other):
  99. if type(self) != type(other):
  100. return cmp(type(self), type(other))
  101. return cmp(list(self), list(other))
  102. def __repr__(self, _track=[]):
  103. if id(self) in _track:
  104. return '...'
  105. _track.append(id(self))
  106. r = 'deque(%r, maxlen=%s)' % (list(self), self.maxlen)
  107. _track.remove(id(self))
  108. return r
  109. def __getstate__(self):
  110. return (tuple(self),)
  111. def __setstate__(self, s):
  112. self.__init__(s[0])
  113. def __hash__(self):
  114. raise TypeError
  115. def __copy__(self):
  116. return self.__class__(self)
  117. def __deepcopy__(self, memo={}):
  118. from copy import deepcopy
  119. result = self.__class__()
  120. memo[id(self)] = result
  121. result.__init__(deepcopy(tuple(self), memo))
  122. return result
  123. #==============================================================================
  124. # threading.Event
  125. #==============================================================================
  126. if sys.version_info >= (2, 6):
  127. from threading import Event, Thread
  128. else:
  129. from threading import _Verbose, Lock, Thread, _time, \
  130. _allocate_lock, RLock, _sleep
  131. def Condition(*args, **kwargs):
  132. return _Condition(*args, **kwargs)
  133. class _Condition(_Verbose):
  134. def __init__(self, lock=None, verbose=None):
  135. _Verbose.__init__(self, verbose)
  136. if lock is None:
  137. lock = RLock()
  138. self.__lock = lock
  139. # Export the lock's acquire() and release() methods
  140. self.acquire = lock.acquire
  141. self.release = lock.release
  142. # If the lock defines _release_save() and/or _acquire_restore(),
  143. # these override the default implementations (which just call
  144. # release() and acquire() on the lock). Ditto for _is_owned().
  145. try:
  146. self._release_save = lock._release_save
  147. except AttributeError:
  148. pass
  149. try:
  150. self._acquire_restore = lock._acquire_restore
  151. except AttributeError:
  152. pass
  153. try:
  154. self._is_owned = lock._is_owned
  155. except AttributeError:
  156. pass
  157. self.__waiters = []
  158. def __enter__(self):
  159. return self.__lock.__enter__()
  160. def __exit__(self, *args):
  161. return self.__lock.__exit__(*args)
  162. def __repr__(self):
  163. return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
  164. def _release_save(self):
  165. self.__lock.release() # No state to save
  166. def _acquire_restore(self, x):
  167. self.__lock.acquire() # Ignore saved state
  168. def _is_owned(self):
  169. # Return True if lock is owned by current_thread.
  170. # This method is called only if __lock doesn't have _is_owned().
  171. if self.__lock.acquire(0):
  172. self.__lock.release()
  173. return False
  174. else:
  175. return True
  176. def wait(self, timeout=None):
  177. if not self._is_owned():
  178. raise RuntimeError("cannot wait on un-acquired lock")
  179. waiter = _allocate_lock()
  180. waiter.acquire()
  181. self.__waiters.append(waiter)
  182. saved_state = self._release_save()
  183. try: # restore state no matter what (e.g., KeyboardInterrupt)
  184. if timeout is None:
  185. waiter.acquire()
  186. if __debug__:
  187. self._note("%s.wait(): got it", self)
  188. else:
  189. # Balancing act: We can't afford a pure busy loop, so we
  190. # have to sleep; but if we sleep the whole timeout time,
  191. # we'll be unresponsive. The scheme here sleeps very
  192. # little at first, longer as time goes on, but never longer
  193. # than 20 times per second (or the timeout time remaining).
  194. endtime = _time() + timeout
  195. delay = 0.0005 # 500 us -> initial delay of 1 ms
  196. while True:
  197. gotit = waiter.acquire(0)
  198. if gotit:
  199. break
  200. remaining = endtime - _time()
  201. if remaining <= 0:
  202. break
  203. delay = min(delay * 2, remaining, .05)
  204. _sleep(delay)
  205. if not gotit:
  206. if __debug__:
  207. self._note("%s.wait(%s): timed out", self, timeout)
  208. try:
  209. self.__waiters.remove(waiter)
  210. except ValueError:
  211. pass
  212. else:
  213. if __debug__:
  214. self._note("%s.wait(%s): got it", self, timeout)
  215. finally:
  216. self._acquire_restore(saved_state)
  217. def notify(self, n=1):
  218. if not self._is_owned():
  219. raise RuntimeError("cannot notify on un-acquired lock")
  220. __waiters = self.__waiters
  221. waiters = __waiters[:n]
  222. if not waiters:
  223. if __debug__:
  224. self._note("%s.notify(): no waiters", self)
  225. return
  226. self._note("%s.notify(): notifying %d waiter%s", self, n,
  227. n != 1 and "s" or "")
  228. for waiter in waiters:
  229. waiter.release()
  230. try:
  231. __waiters.remove(waiter)
  232. except ValueError:
  233. pass
  234. def notifyAll(self):
  235. self.notify(len(self.__waiters))
  236. notify_all = notifyAll
  237. def Event(*args, **kwargs):
  238. return _Event(*args, **kwargs)
  239. class _Event(_Verbose):
  240. # After Tim Peters' event class (without is_posted())
  241. def __init__(self, verbose=None):
  242. _Verbose.__init__(self, verbose)
  243. self.__cond = Condition(Lock())
  244. self.__flag = False
  245. def isSet(self):
  246. return self.__flag
  247. is_set = isSet
  248. def set(self):
  249. self.__cond.acquire()
  250. try:
  251. self.__flag = True
  252. self.__cond.notify_all()
  253. finally:
  254. self.__cond.release()
  255. def clear(self):
  256. self.__cond.acquire()
  257. try:
  258. self.__flag = False
  259. finally:
  260. self.__cond.release()
  261. def wait(self, timeout=None):
  262. self.__cond.acquire()
  263. try:
  264. if not self.__flag:
  265. self.__cond.wait(timeout)
  266. finally:
  267. self.__cond.release()