]> granicus.if.org Git - python/commitdiff
Issue #11004: Repair edge case in deque.count().
authorRaymond Hettinger <python@rcn.com>
Tue, 25 Jan 2011 21:32:39 +0000 (21:32 +0000)
committerRaymond Hettinger <python@rcn.com>
Tue, 25 Jan 2011 21:32:39 +0000 (21:32 +0000)
(Reviewed by Georg Brandl.)

Also made similar changes to deque.reverse() though this wasn't
strictly necessary (the edge case cannot occur with two pointers
moving to meet in the middle).  Making the change in reverse()
was more a matter of future-proofing.

Lib/test/test_deque.py
Misc/NEWS
Modules/_collectionsmodule.c

index da00c0d206fd2f99d453eaebe3f9fe6d46da0c1c..0dcadeb3c584930cfd984107a5d27a3bac711e43 100644 (file)
@@ -138,6 +138,15 @@ class TestBasic(unittest.TestCase):
         m.d = d
         self.assertRaises(RuntimeError, d.count, 3)
 
+        # test issue11004
+        # block advance failed after rotation aligned elements on right side of block
+        d = deque([None]*16)
+        for i in range(len(d)):
+            d.rotate(-1)
+        d.rotate(1)
+        self.assertEqual(d.count(1), 0)
+        self.assertEqual(d.count(None), 16)
+
     def test_comparisons(self):
         d = deque('xabc'); d.popleft()
         for e in [d, deque('abc'), deque('ab'), deque(), list(d)]:
index 07f493ad9a6e56a2e73a6944eaaeaa5cbfd05ecc..56552055ca5f5df30631d29d0e5f3e97a687a9ae 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -16,6 +16,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #11004: Repaired edge case in deque.count().
+
 - Issue #10974: IDLE no longer crashes if its recent files list includes files
   with non-ASCII characters in their path names.
 
index f4a2c8bd6ee074f0a8124d1ad52904042c164cdd..2391c0d38158107169a75bf4074ea4a598c92a83 100644 (file)
@@ -485,7 +485,8 @@ deque_reverse(dequeobject *deque, PyObject *unused)
         /* Advance left block/index pair */
         leftindex++;
         if (leftindex == BLOCKLEN) {
-            assert (leftblock->rightlink != NULL);
+            if (leftblock->rightlink == NULL)
+                break;
             leftblock = leftblock->rightlink;
             leftindex = 0;
         }
@@ -493,7 +494,8 @@ deque_reverse(dequeobject *deque, PyObject *unused)
         /* Step backwards with the right block/index pair */
         rightindex--;
         if (rightindex == -1) {
-            assert (rightblock->leftlink != NULL);
+            if (rightblock->leftlink == NULL)
+                break;
             rightblock = rightblock->leftlink;
             rightindex = BLOCKLEN - 1;
         }
@@ -509,7 +511,7 @@ deque_count(dequeobject *deque, PyObject *v)
 {
     block *leftblock = deque->leftblock;
     Py_ssize_t leftindex = deque->leftindex;
-    Py_ssize_t n = (deque->len);
+    Py_ssize_t n = deque->len;
     Py_ssize_t i;
     Py_ssize_t count = 0;
     PyObject *item;
@@ -533,7 +535,8 @@ deque_count(dequeobject *deque, PyObject *v)
         /* Advance left block/index pair */
         leftindex++;
         if (leftindex == BLOCKLEN) {
-            assert (leftblock->rightlink != NULL);
+            if (leftblock->rightlink == NULL)  /* can occur when i==n-1 */
+                break;
             leftblock = leftblock->rightlink;
             leftindex = 0;
         }