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