]> granicus.if.org Git - python/commitdiff
Fix variants of deque.extend: d.extend(d) d+=d d.extendleft(d)
authorRaymond Hettinger <python@rcn.com>
Thu, 10 Dec 2009 03:03:02 +0000 (03:03 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 10 Dec 2009 03:03:02 +0000 (03:03 +0000)
Lib/test/test_deque.py
Misc/NEWS
Modules/_collectionsmodule.c

index cdb0dab0f040f9004d89481ca2d3a15365f7407d..8120e8b7835434caa9a6a1dea76f9529c9ca98b6 100644 (file)
@@ -136,12 +136,23 @@ class TestBasic(unittest.TestCase):
         self.assertRaises(TypeError, d.extend, 1)
         d.extend('bcd')
         self.assertEqual(list(d), list('abcd'))
+        d.extend(d)
+        self.assertEqual(list(d), list('abcdabcd'))
+
+    def test_iadd(self):
+        d = deque('a')
+        d += 'bcd'
+        self.assertEqual(list(d), list('abcd'))
+        d += d
+        self.assertEqual(list(d), list('abcdabcd'))
 
     def test_extendleft(self):
         d = deque('a')
         self.assertRaises(TypeError, d.extendleft, 1)
         d.extendleft('bcd')
         self.assertEqual(list(d), list(reversed('abcd')))
+        d.extendleft(d)
+        self.assertEqual(list(d), list('abcddcba'))
         d = deque()
         d.extendleft(range(1000))
         self.assertEqual(list(d), list(reversed(range(1000))))
index b99dbeff8e8fc2be7f87f0908cdd0b3619c2785d..8f051b74ea37282e003490c9f4fecf0b3b35144c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -159,6 +159,8 @@ Library
 
 - Add a reverse() method to collections.deque().
 
+- Fix variations of extending deques:  d.extend(d)  d.extendleft(d)  d+=d
+
 - Issue #6986: Fix crash in the JSON C accelerator when called with the
   wrong parameter types.  Patch by Victor Stinner.
 
index cdcf4ef9884661acf0c47244f67a2b509a14bb0f..ffb2a8066d94243da08391a0ee1c9bbd1ad59a22 100644 (file)
@@ -298,6 +298,17 @@ deque_extend(dequeobject *deque, PyObject *iterable)
 {
        PyObject *it, *item;
 
+       /* Handle case where id(deque) == id(iterable) */
+       if ((PyObject *)deque == iterable) {
+               PyObject *result;
+               PyObject *s = PySequence_List(iterable);
+               if (s == NULL)
+                       return NULL;
+               result = deque_extend(deque, s);
+               Py_DECREF(s);
+               return result;
+       }
+
        it = PyObject_GetIter(iterable);
        if (it == NULL)
                return NULL;
@@ -339,6 +350,17 @@ deque_extendleft(dequeobject *deque, PyObject *iterable)
 {
        PyObject *it, *item;
 
+       /* Handle case where id(deque) == id(iterable) */
+       if ((PyObject *)deque == iterable) {
+               PyObject *result;
+               PyObject *s = PySequence_List(iterable);
+               if (s == NULL)
+                       return NULL;
+               result = deque_extendleft(deque, s);
+               Py_DECREF(s);
+               return result;
+       }
+
        it = PyObject_GetIter(iterable);
        if (it == NULL)
                return NULL;
@@ -375,6 +397,19 @@ deque_extendleft(dequeobject *deque, PyObject *iterable)
 PyDoc_STRVAR(extendleft_doc,
 "Extend the left side of the deque with elements from the iterable");
 
+static PyObject *
+deque_inplace_concat(dequeobject *deque, PyObject *other)
+{
+       PyObject *result;
+
+       result = deque_extend(deque, other);
+       if (result == NULL)
+               return result;
+       Py_DECREF(result);
+       Py_INCREF(deque);
+       return (PyObject *)deque;
+}
+
 static int
 _deque_rotate(dequeobject *deque, Py_ssize_t n)
 {
@@ -875,6 +910,11 @@ static PySequenceMethods deque_as_sequence = {
        (ssizeargfunc)deque_item,       /* sq_item */
        0,                              /* sq_slice */
        (ssizeobjargproc)deque_ass_item,        /* sq_ass_item */
+       0,                              /* sq_ass_slice */
+       0,                              /* sq_contains */
+       (binaryfunc)deque_inplace_concat,       /* sq_inplace_concat */
+       0,                              /* sq_inplace_repeat */
+
 };
 
 /* deque object ********************************************************/