deque_traverse():  If the deque had one block, and its rightindex was
BLOCKLEN-1, this assert-failed in a debug build, or went wild with a
NULL pointer in a release build.  Reported on c.l.py by Stefan Behnel.
diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py
index c0024ac..300e9af 100644
--- a/Lib/test/test_deque.py
+++ b/Lib/test/test_deque.py
@@ -324,6 +324,15 @@
         for s in ('abcd', xrange(2000)):
             self.assertEqual(list(reversed(deque(s))), list(reversed(s)))
 
+    def test_gc_doesnt_blowup(self):
+        import gc
+        # This used to assert-fail in deque_traverse() under a debug
+        # build, or run wild with a NULL pointer in a release build.
+        d = deque()
+        for i in xrange(100):
+            d.append(1)
+            gc.collect()
+
 def R(seqn):
     'Regular generator'
     for i in seqn:
diff --git a/Modules/collectionsmodule.c b/Modules/collectionsmodule.c
index f8a6f61..196cbe2 100644
--- a/Modules/collectionsmodule.c
+++ b/Modules/collectionsmodule.c
@@ -478,19 +478,22 @@
 static int
 deque_traverse(dequeobject *deque, visitproc visit, void *arg)
 {
-	block * b = deque->leftblock;
-	int index = deque->leftindex;
+	block *b;
 	PyObject *item;
+	int index;
+	int indexlo = deque->leftindex;
 
-	while (b != deque->rightblock || index <= deque->rightindex) {
-		item = b->data[index];
-		index++;
-		if (index == BLOCKLEN ) {
-			assert(b->rightlink != NULL);
-			b = b->rightlink;
-			index = 0;
+	assert(deque->leftblock != NULL);
+	for (b = deque->leftblock; b != NULL; b = b->rightlink) {
+		const int indexhi = b == deque->rightblock ?
+					 deque->rightindex :
+				    	 BLOCKLEN - 1;
+
+		for (index = indexlo; index <= indexhi; ++index) {
+			item = b->data[index];
+			Py_VISIT(item);
 		}
-		Py_VISIT(item);
+		indexlo = 0;
 	}
 	return 0;
 }