]> 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 06:00:33 +0000 (06:00 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 10 Dec 2009 06:00:33 +0000 (06:00 +0000)
Lib/test/test_deque.py
Misc/NEWS
Modules/_collectionsmodule.c

index 86810f2e6ad2e5880d096d8aa268ce50ad28b694..23641ba18dcc21432c734f726c7cf80544599672 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 845ed7afa836e671d081eb6eb6a7b5e3d7d47bcf..3cd0b4259e9c1af8ed7b5714906c16df3a64c39c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -513,6 +513,8 @@ Core and Builtins
 Library
 -------
 
+- 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 1873cabc5b6b7e352565fd7618cef7d9e081e1f1..97b390539ffdb8e00e48f083af6d438275574470 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)
 {
@@ -891,6 +926,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 ********************************************************/