[pypy-svn] pypy collections-module: getitem(), setitem(), and maybe delitem() if we already had rotate()
arigo
commits-noreply at bitbucket.org
Tue Feb 15 16:42:58 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: collections-module
Changeset: r41972:95ee17576483
Date: 2011-02-15 16:30 +0100
http://bitbucket.org/pypy/pypy/changeset/95ee17576483/
Log: getitem(), setitem(), and maybe delitem() if we already had rotate()
diff --git a/pypy/module/_collections/test/test_deque.py b/pypy/module/_collections/test/test_deque.py
--- a/pypy/module/_collections/test/test_deque.py
+++ b/pypy/module/_collections/test/test_deque.py
@@ -139,49 +139,31 @@
def test_getitem(self):
from _collections import deque
n = 200
- d = deque(xrange(n))
- l = range(n)
- for i in xrange(n):
- d.popleft()
- l.pop(0)
- if i & 1:
- d.append(i)
- l.append(i)
- for j in xrange(-len(l), len(l)):
- assert d[j] == l[j]
-
- d = deque('superman')
- self.assertEqual(d[0], 's')
- self.assertEqual(d[-1], 'n')
- d = deque()
- self.assertRaises(IndexError, d.__getitem__, 0)
- self.assertRaises(IndexError, d.__getitem__, -1)
+ l = xrange(1000, 1000 + n)
+ d = deque(l)
+ for j in xrange(-n, n):
+ assert d[j] == l[j]
+ raises(IndexError, "d[-n-1]")
+ raises(IndexError, "d[n]")
def test_setitem(self):
+ from _collections import deque
n = 200
d = deque(xrange(n))
for i in xrange(n):
d[i] = 10 * i
- self.assertEqual(list(d), [10*i for i in xrange(n)])
+ assert list(d) == [10*i for i in xrange(n)]
l = list(d)
- for i in xrange(1-n, 0, -1):
+ for i in xrange(1-n, 0, -3):
d[i] = 7*i
l[i] = 7*i
- self.assertEqual(list(d), l)
+ assert list(d) == l
def test_delitem(self):
- n = 500 # O(n**2) test, don't make this too big
- d = deque(xrange(n))
- self.assertRaises(IndexError, d.__delitem__, -n-1)
- self.assertRaises(IndexError, d.__delitem__, n)
- for i in xrange(n):
- self.assertEqual(len(d), n-i)
- j = random.randrange(-len(d), len(d))
- val = d[j]
- self.assertIn(val, d)
- del d[j]
- self.assertNotIn(val, d)
- self.assertEqual(len(d), 0)
+ from _collections import deque
+ d = deque("abcdef")
+ del d[-2]
+ assert list(d) == list("abcdf")
def test_reverse(self):
n = 500 # O(n**2) test, don't make this too big
diff --git a/pypy/module/_collections/interp_deque.py b/pypy/module/_collections/interp_deque.py
--- a/pypy/module/_collections/interp_deque.py
+++ b/pypy/module/_collections/interp_deque.py
@@ -289,14 +289,58 @@
def ge(self, w_other):
return self.compare(w_other, 'ge')
+ def locate(self, i):
+ if i < (self.len >> 1):
+ i += self.leftindex
+ b = self.leftblock
+ while i >= BLOCKLEN:
+ b = b.rightlink
+ i -= BLOCKLEN
+ else:
+ i = i - self.len + 1 # then i <= 0
+ i += self.rightindex
+ b = self.rightblock
+ while i < 0:
+ b = b.leftlink
+ i += BLOCKLEN
+ assert i >= 0
+ return b, i
+
@unwrap_spec('self', W_Root)
def getitem(self, w_index):
space = self.space
start, stop, step = space.decode_index(w_index, self.len)
if step == 0: # index only
- return space.wrap(self.mmap.getitem(start))
+ b, i = self.locate(start)
+ return b.data[i]
else:
- xxx
+ raise OperationError(self.w_TypeError,
+ self.wrap("deque[:] is not supported"))
+
+ @unwrap_spec('self', W_Root, W_Root)
+ def setitem(self, w_index, w_newobj):
+ space = self.space
+ start, stop, step = space.decode_index(w_index, self.len)
+ if step == 0: # index only
+ b, i = self.locate(start)
+ b.data[i] = w_newobj
+ else:
+ raise OperationError(self.w_TypeError,
+ self.wrap("deque[:] is not supported"))
+
+ @unwrap_spec('self', W_Root)
+ def delitem(self, w_index):
+ space = self.space
+ start, stop, step = space.decode_index(w_index, self.len)
+ if step == 0: # index only
+ # delitem() implemented in terms of rotate for simplicity and
+ # reasonable performance near the end points.
+ self.rotate(-i)
+ self.popleft()
+ self.rotate(i)
+ else:
+ raise OperationError(self.w_TypeError,
+ self.wrap("deque[:] is not supported"))
def get_maxlen(space, self):
if self.maxlen == sys.maxint:
@@ -359,6 +403,8 @@
__ge__ = interp2app(W_Deque.ge),
__iadd__ = interp2app(W_Deque.iadd),
__getitem__ = interp2app(W_Deque.getitem),
+ __setitem__ = interp2app(W_Deque.setitem),
+ __delitem__ = interp2app(W_Deque.delitem),
maxlen = GetSetProperty(W_Deque.get_maxlen),
)
More information about the Pypy-commit
mailing list