changeset 2729:e9e7c40b4f1a beta

added deque with maxlen for py2.5 compat
author Marcin Kuzminski <marcin@python-works.com>
date Wed, 22 Aug 2012 12:09:49 +0200
parents 6341084b7a2f
children 7949bc80b3b1
files rhodecode/lib/compat.py rhodecode/lib/subprocessio.py
diffstat 2 files changed, 128 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/lib/compat.py	Wed Aug 22 02:14:27 2012 +0200
+++ b/rhodecode/lib/compat.py	Wed Aug 22 12:09:49 2012 +0200
@@ -25,7 +25,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
-from rhodecode import __platform__, PLATFORM_WIN
+from rhodecode import __platform__, PLATFORM_WIN, __py_version__
 
 #==============================================================================
 # json
@@ -404,3 +404,129 @@
     from io import BytesIO
 except ImportError:
     from cStringIO import StringIO as BytesIO
+
+
+#==============================================================================
+# deque
+#==============================================================================
+
+if __py_version__ >= (2, 6):
+    from collections import deque
+else:
+    #need to implement our own deque with maxlen
+    class deque(object):
+
+        def __init__(self, iterable=(), maxlen=-1):
+            if not hasattr(self, 'data'):
+                self.left = self.right = 0
+                self.data = {}
+            self.maxlen = maxlen
+            self.extend(iterable)
+
+        def append(self, x):
+            self.data[self.right] = x
+            self.right += 1
+            if self.maxlen != -1 and len(self) > self.maxlen:
+                self.popleft()
+
+        def appendleft(self, x):
+            self.left -= 1
+            self.data[self.left] = x
+            if self.maxlen != -1 and len(self) > self.maxlen:
+                self.pop()
+
+        def pop(self):
+            if self.left == self.right:
+                raise IndexError('cannot pop from empty deque')
+            self.right -= 1
+            elem = self.data[self.right]
+            del self.data[self.right]
+            return elem
+
+        def popleft(self):
+            if self.left == self.right:
+                raise IndexError('cannot pop from empty deque')
+            elem = self.data[self.left]
+            del self.data[self.left]
+            self.left += 1
+            return elem
+
+        def clear(self):
+            self.data.clear()
+            self.left = self.right = 0
+
+        def extend(self, iterable):
+            for elem in iterable:
+                self.append(elem)
+
+        def extendleft(self, iterable):
+            for elem in iterable:
+                self.appendleft(elem)
+
+        def rotate(self, n=1):
+            if self:
+                n %= len(self)
+                for i in xrange(n):
+                    self.appendleft(self.pop())
+
+        def __getitem__(self, i):
+            if i < 0:
+                i += len(self)
+            try:
+                return self.data[i + self.left]
+            except KeyError:
+                raise IndexError
+
+        def __setitem__(self, i, value):
+            if i < 0:
+                i += len(self)
+            try:
+                self.data[i + self.left] = value
+            except KeyError:
+                raise IndexError
+
+        def __delitem__(self, i):
+            size = len(self)
+            if not (-size <= i < size):
+                raise IndexError
+            data = self.data
+            if i < 0:
+                i += size
+            for j in xrange(self.left + i, self.right - 1):
+                data[j] = data[j + 1]
+            self.pop()
+
+        def __len__(self):
+            return self.right - self.left
+
+        def __cmp__(self, other):
+            if type(self) != type(other):
+                return cmp(type(self), type(other))
+            return cmp(list(self), list(other))
+
+        def __repr__(self, _track=[]):
+            if id(self) in _track:
+                return '...'
+            _track.append(id(self))
+            r = 'deque(%r, maxlen=%s)' % (list(self), self.maxlen)
+            _track.remove(id(self))
+            return r
+
+        def __getstate__(self):
+            return (tuple(self),)
+
+        def __setstate__(self, s):
+            self.__init__(s[0])
+
+        def __hash__(self):
+            raise TypeError
+
+        def __copy__(self):
+            return self.__class__(self)
+
+        def __deepcopy__(self, memo={}):
+            from copy import deepcopy
+            result = self.__class__()
+            memo[id(self)] = result
+            result.__init__(deepcopy(tuple(self), memo))
+            return result
--- a/rhodecode/lib/subprocessio.py	Wed Aug 22 02:14:27 2012 +0200
+++ b/rhodecode/lib/subprocessio.py	Wed Aug 22 12:09:49 2012 +0200
@@ -25,7 +25,7 @@
 import os
 import subprocess
 import threading
-from collections import deque
+from rhodecode.lib.compat import deque
 
 
 class StreamFeeder(threading.Thread):