* balance the left/right search for getitem.
* use assertions instead of tests after internal calls that can't fail.
* expand test coverage
diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py
index 13800ea..dc0cc6f 100644
--- a/Lib/test/test_deque.py
+++ b/Lib/test/test_deque.py
@@ -6,9 +6,14 @@
import cPickle as pickle
from cStringIO import StringIO
import random
+import os
BIG = 100000
+def fail():
+ raise SyntaxError
+ yield 1
+
class TestBasic(unittest.TestCase):
def test_basics(self):
@@ -58,6 +63,10 @@
self.assertRaises(TypeError, d.extendleft, 1)
d.extendleft('bcd')
self.assertEqual(list(d), list(reversed('abcd')))
+ d = deque()
+ d.extendleft(range(1000))
+ self.assertEqual(list(d), list(reversed(range(1000))))
+ self.assertRaises(SyntaxError, d.extendleft, fail())
def test_getitem(self):
n = 200
@@ -151,6 +160,13 @@
dr()
self.assertEqual(tuple(d), tuple(e))
+ self.assertRaises(TypeError, d.rotate, 'x') # Wrong arg type
+ self.assertRaises(TypeError, d.rotate, 1, 10) # Too many args
+
+ d = deque()
+ d.rotate() # rotate an empty deque
+ self.assertEqual(d, deque())
+
def test_len(self):
d = deque('ab')
self.assertEqual(len(d), 2)
@@ -178,6 +194,8 @@
d.clear()
self.assertEqual(len(d), 0)
self.assertEqual(list(d), [])
+ d.clear() # clear an emtpy deque
+ self.assertEqual(list(d), [])
def test_repr(self):
d = deque(xrange(200))
@@ -189,10 +207,19 @@
def test_print(self):
d = deque(xrange(200))
d.append(d)
- f = StringIO()
- print >> f, d,
- self.assertEqual(f.getvalue(), repr(d))
- f.close()
+ try:
+ fo = open(test_support.TESTFN, "wb")
+ print >> fo, d,
+ fo.close()
+ fo = open(test_support.TESTFN, "rb")
+ self.assertEqual(fo.read(), repr(d))
+ finally:
+ fo.close()
+ os.remove(test_support.TESTFN)
+
+ def test_init(self):
+ self.assertRaises(TypeError, deque, 'abc', 2);
+ self.assertRaises(TypeError, deque, 1);
def test_hash(self):
self.assertRaises(TypeError, hash, deque('abc'))
diff --git a/Modules/collectionsmodule.c b/Modules/collectionsmodule.c
index da276ce..367b444 100644
--- a/Modules/collectionsmodule.c
+++ b/Modules/collectionsmodule.c
@@ -245,7 +245,7 @@
deque->leftblock->data[deque->leftindex] = item;
}
Py_DECREF(it);
- if (PyErr_Occurred())
+ if (PyErr_Occurred())
return NULL;
Py_RETURN_NONE;
}
@@ -274,8 +274,7 @@
for (i=0 ; i<n ; i++) {
item = deque_pop(deque, NULL);
- if (item == NULL)
- return NULL;
+ assert (item != NULL);
rv = deque_appendleft(deque, item);
Py_DECREF(item);
if (rv == NULL)
@@ -284,8 +283,7 @@
}
for (i=0 ; i>n ; i--) {
item = deque_popleft(deque, NULL);
- if (item == NULL)
- return NULL;
+ assert (item != NULL);
rv = deque_append(deque, item);
Py_DECREF(item);
if (rv == NULL)
@@ -311,8 +309,7 @@
while (deque_len(deque)) {
item = deque_pop(deque, NULL);
- if (item == NULL)
- return -1;
+ assert (item != NULL);
Py_DECREF(item);
}
assert(deque->leftblock == deque->rightblock &&
@@ -388,8 +385,7 @@
Py_DECREF(item);
item = deque_popleft(deque, NULL);
- if (item == NULL)
- goto fail;
+ assert (item != NULL);
Py_DECREF(item);
item = deque_rotate(deque, plus_i);
@@ -409,9 +405,9 @@
{
PyObject *old_value;
block *b;
- int n;
+ int n, len=deque->len, halflen=(len+1)>>1, index=i;
- if (i < 0 || i >= deque->len) {
+ if (i < 0 || i >= len) {
PyErr_SetString(PyExc_IndexError,
"deque index out of range");
return -1;
@@ -422,12 +418,12 @@
i += deque->leftindex;
n = i / BLOCKLEN;
i %= BLOCKLEN;
- if (i < (deque->len >> 1)) {
+ if (index <= halflen) {
b = deque->leftblock;
while (n--)
b = b->rightlink;
} else {
- n = (deque->leftindex + deque->len - 1) / BLOCKLEN - n;
+ n = (deque->leftindex + len - 1) / BLOCKLEN - n;
b = deque->rightblock;
while (n--)
b = b->leftlink;
@@ -442,8 +438,10 @@
static PyObject *
deque_clearmethod(dequeobject *deque)
{
- if (deque_clear(deque) == -1)
- return NULL;
+ int rv;
+
+ rv = deque_clear(deque);
+ assert (rv != -1);
Py_RETURN_NONE;
}