summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2009-12-10 03:03:02 (GMT)
committerRaymond Hettinger <python@rcn.com>2009-12-10 03:03:02 (GMT)
commit3f9afd816de4067b8277bfe0241cf15d34b13e47 (patch)
tree4701c6f2330249aeee9a01bd061b2cee3d064e2d
parent0f6cae0bffa52b16e09fce41c388b1ef70404c28 (diff)
downloadcpython-3f9afd816de4067b8277bfe0241cf15d34b13e47.zip
cpython-3f9afd816de4067b8277bfe0241cf15d34b13e47.tar.gz
cpython-3f9afd816de4067b8277bfe0241cf15d34b13e47.tar.bz2
Fix variants of deque.extend: d.extend(d) d+=d d.extendleft(d)
-rw-r--r--Lib/test/test_deque.py11
-rw-r--r--Misc/NEWS2
-rw-r--r--Modules/_collectionsmodule.c40
3 files changed, 53 insertions, 0 deletions
diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py
index cdb0dab..8120e8b 100644
--- a/Lib/test/test_deque.py
+++ b/Lib/test/test_deque.py
@@ -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))))
diff --git a/Misc/NEWS b/Misc/NEWS
index b99dbef..8f051b7 100644
--- 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.
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index cdcf4ef..ffb2a80 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -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 ********************************************************/