[pypy-svn] r77756 - in pypy/branch/fast-forward/lib_pypy: . pypy_test
afa at codespeak.net
afa at codespeak.net
Sun Oct 10 13:32:25 CEST 2010
Author: afa
Date: Sun Oct 10 13:32:23 2010
New Revision: 77756
Modified:
pypy/branch/fast-forward/lib_pypy/_collections.py
pypy/branch/fast-forward/lib_pypy/pypy_test/test_collections.py
Log:
Add deque.maxlen
Modified: pypy/branch/fast-forward/lib_pypy/_collections.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/_collections.py (original)
+++ pypy/branch/fast-forward/lib_pypy/_collections.py Sun Oct 10 13:32:23 2010
@@ -18,6 +18,12 @@
RGTLNK = n+1
BLOCKSIZ = n+2
+# The deque's size limit is d.maxlen. The limit can be zero or positive, or
+# None. After an item is added to a deque, we check to see if the size has
+# grown past the limit. If it has, we get the size back down to the limit by
+# popping an item off of the opposite end. The methods that can trigger this
+# are append(), appendleft(), extend(), and extendleft().
+
class deque(object):
def __new__(cls, iterable=(), *args, **kw):
@@ -25,7 +31,11 @@
self.clear()
return self
- def __init__(self, iterable=()):
+ def __init__(self, iterable=(), maxlen=None):
+ if maxlen is not None:
+ if maxlen < 0:
+ raise ValueError("maxlen must be non-negative")
+ self.maxlen = maxlen
add = self.append
for elem in iterable:
add(elem)
@@ -48,6 +58,8 @@
self.rightndx = 0
self.length += 1
self.right[self.rightndx] = x
+ if self.maxlen is not None and self.length > self.maxlen:
+ self.popleft()
def appendleft(self, x):
self.state += 1
@@ -60,6 +72,8 @@
self.leftndx = n-1
self.length += 1
self.left[self.leftndx] = x
+ if self.maxlen is not None and self.length > self.maxlen:
+ self.pop()
def extend(self, iterable):
for elem in iterable:
@@ -144,7 +158,10 @@
else:
self.__dict__[threadlocalattr] = True
try:
- return 'deque(%r)' % (list(self),)
+ if self.maxlen is not None:
+ return 'deque(%r, maxlen=%s)' % (list(self), self.maxlen)
+ else:
+ return 'deque(%r)' % (list(self),)
finally:
del self.__dict__[threadlocalattr]
@@ -249,13 +266,13 @@
self.rotate(-index)
def __reduce_ex__(self, proto):
- return type(self), (), self.__dict__, iter(self), None
+ return type(self), (list(self), self.maxlen)
def __hash__(self):
raise TypeError, "deque objects are unhashable"
def __copy__(self):
- return self.__class__(self)
+ return self.__class__(self, self.maxlen)
# XXX make comparison more efficient
def __eq__(self, other):
Modified: pypy/branch/fast-forward/lib_pypy/pypy_test/test_collections.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/pypy_test/test_collections.py (original)
+++ pypy/branch/fast-forward/lib_pypy/pypy_test/test_collections.py Sun Oct 10 13:32:23 2010
@@ -14,7 +14,21 @@
d = collections.deque([MutatingCmp()])
py.test.raises(IndexError, d.remove, 1)
-
+
+def test_deque_maxlen():
+ d = collections.deque([], 3)
+ d.append(1); d.append(2); d.append(3); d.append(4)
+ assert list(d) == [2, 3, 4]
+ assert repr(d) == "deque([2, 3, 4], maxlen=3)"
+
+ import pickle
+ d2 = pickle.loads(pickle.dumps(d))
+ assert repr(d2) == "deque([2, 3, 4], maxlen=3)"
+
+ import copy
+ d3 = copy.copy(d)
+ assert repr(d3) == "deque([2, 3, 4], maxlen=3)"
+
class SubclassWithKwargs(collections.deque):
def __init__(self, newarg=1):
collections.deque.__init__(self)
More information about the Pypy-commit
mailing list