]> granicus.if.org Git - python/commitdiff
Small optimization for corner case where maxlen==0.
authorRaymond Hettinger <python@rcn.com>
Tue, 10 Mar 2009 09:31:48 +0000 (09:31 +0000)
committerRaymond Hettinger <python@rcn.com>
Tue, 10 Mar 2009 09:31:48 +0000 (09:31 +0000)
Lib/test/test_deque.py
Modules/_collectionsmodule.c

index 02dadef4fbd46e48085fe4f89c00daf757281600..dcef24656ad189d86e3a1e0008e7a85556133151 100644 (file)
@@ -50,7 +50,9 @@ class TestBasic(unittest.TestCase):
     def test_maxlen(self):
         self.assertRaises(ValueError, deque, 'abc', -1)
         self.assertRaises(ValueError, deque, 'abc', -2)
-        d = deque(range(10), maxlen=3)
+        it = iter(range(10))
+        d = deque(it, maxlen=3)
+        self.assertEqual(list(it), [])
         self.assertEqual(repr(d), 'deque([7, 8, 9], maxlen=3)')
         self.assertEqual(list(d), range(7, 10))
         self.assertEqual(d, deque(range(10), 3))
@@ -87,6 +89,21 @@ class TestBasic(unittest.TestCase):
             fo.close()
             test_support.unlink(test_support.TESTFN)
 
+    def test_maxlen_zero(self):
+        it = iter(range(100))
+        deque(it, maxlen=0)
+        self.assertEqual(list(it), [])
+
+        it = iter(range(100))
+        d = deque(maxlen=0)
+        d.extend(it)
+        self.assertEqual(list(it), [])
+
+        it = iter(range(100))
+        d = deque(maxlen=0)
+        d.extendleft(it)
+        self.assertEqual(list(it), [])
+
     def test_comparisons(self):
         d = deque('xabc'); d.popleft()
         for e in [d, deque('abc'), deque('ab'), deque(), list(d)]:
index 002953203247cf61490170f5c45e43655156b4f4..9532f1b51c25b63e8cdd75a2a2d0c5469c788f20 100644 (file)
@@ -276,6 +276,23 @@ deque_appendleft(dequeobject *deque, PyObject *item)
 
 PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque.");
 
+
+/* Run an iterator to exhaustion.  Shortcut for 
+   the extend/extendleft methods when maxlen == 0. */
+static PyObject*
+consume_iterator(PyObject *it)
+{
+       PyObject *item;
+
+       while ((item = PyIter_Next(it)) != NULL) {
+               Py_DECREF(item);
+       }
+       Py_DECREF(it);
+       if (PyErr_Occurred())
+               return NULL;
+       Py_RETURN_NONE;
+}
+
 static PyObject *
 deque_extend(dequeobject *deque, PyObject *iterable)
 {
@@ -285,6 +302,9 @@ deque_extend(dequeobject *deque, PyObject *iterable)
        if (it == NULL)
                return NULL;
 
+       if (deque->maxlen == 0)
+               return consume_iterator(it);
+
        while ((item = PyIter_Next(it)) != NULL) {
                deque->state++;
                if (deque->rightindex == BLOCKLEN-1) {
@@ -323,6 +343,9 @@ deque_extendleft(dequeobject *deque, PyObject *iterable)
        if (it == NULL)
                return NULL;
 
+       if (deque->maxlen == 0)
+               return consume_iterator(it);
+
        while ((item = PyIter_Next(it)) != NULL) {
                deque->state++;
                if (deque->leftindex == 0) {