Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3f9afd8

Browse files
committed
Fix variants of deque.extend: d.extend(d) d+=d d.extendleft(d)
1 parent 0f6cae0 commit 3f9afd8

3 files changed

Lines changed: 53 additions & 0 deletions

File tree

Lib/test/test_deque.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,23 @@ def test_extend(self):
136136
self.assertRaises(TypeError, d.extend, 1)
137137
d.extend('bcd')
138138
self.assertEqual(list(d), list('abcd'))
139+
d.extend(d)
140+
self.assertEqual(list(d), list('abcdabcd'))
141+
142+
def test_iadd(self):
143+
d = deque('a')
144+
d += 'bcd'
145+
self.assertEqual(list(d), list('abcd'))
146+
d += d
147+
self.assertEqual(list(d), list('abcdabcd'))
139148

140149
def test_extendleft(self):
141150
d = deque('a')
142151
self.assertRaises(TypeError, d.extendleft, 1)
143152
d.extendleft('bcd')
144153
self.assertEqual(list(d), list(reversed('abcd')))
154+
d.extendleft(d)
155+
self.assertEqual(list(d), list('abcddcba'))
145156
d = deque()
146157
d.extendleft(range(1000))
147158
self.assertEqual(list(d), list(reversed(range(1000))))

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ Library
159159

160160
- Add a reverse() method to collections.deque().
161161

162+
- Fix variations of extending deques: d.extend(d) d.extendleft(d) d+=d
163+
162164
- Issue #6986: Fix crash in the JSON C accelerator when called with the
163165
wrong parameter types. Patch by Victor Stinner.
164166

Modules/_collectionsmodule.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,17 @@ deque_extend(dequeobject *deque, PyObject *iterable)
298298
{
299299
PyObject *it, *item;
300300

301+
/* Handle case where id(deque) == id(iterable) */
302+
if ((PyObject *)deque == iterable) {
303+
PyObject *result;
304+
PyObject *s = PySequence_List(iterable);
305+
if (s == NULL)
306+
return NULL;
307+
result = deque_extend(deque, s);
308+
Py_DECREF(s);
309+
return result;
310+
}
311+
301312
it = PyObject_GetIter(iterable);
302313
if (it == NULL)
303314
return NULL;
@@ -339,6 +350,17 @@ deque_extendleft(dequeobject *deque, PyObject *iterable)
339350
{
340351
PyObject *it, *item;
341352

353+
/* Handle case where id(deque) == id(iterable) */
354+
if ((PyObject *)deque == iterable) {
355+
PyObject *result;
356+
PyObject *s = PySequence_List(iterable);
357+
if (s == NULL)
358+
return NULL;
359+
result = deque_extendleft(deque, s);
360+
Py_DECREF(s);
361+
return result;
362+
}
363+
342364
it = PyObject_GetIter(iterable);
343365
if (it == NULL)
344366
return NULL;
@@ -375,6 +397,19 @@ deque_extendleft(dequeobject *deque, PyObject *iterable)
375397
PyDoc_STRVAR(extendleft_doc,
376398
"Extend the left side of the deque with elements from the iterable");
377399

400+
static PyObject *
401+
deque_inplace_concat(dequeobject *deque, PyObject *other)
402+
{
403+
PyObject *result;
404+
405+
result = deque_extend(deque, other);
406+
if (result == NULL)
407+
return result;
408+
Py_DECREF(result);
409+
Py_INCREF(deque);
410+
return (PyObject *)deque;
411+
}
412+
378413
static int
379414
_deque_rotate(dequeobject *deque, Py_ssize_t n)
380415
{
@@ -875,6 +910,11 @@ static PySequenceMethods deque_as_sequence = {
875910
(ssizeargfunc)deque_item, /* sq_item */
876911
0, /* sq_slice */
877912
(ssizeobjargproc)deque_ass_item, /* sq_ass_item */
913+
0, /* sq_ass_slice */
914+
0, /* sq_contains */
915+
(binaryfunc)deque_inplace_concat, /* sq_inplace_concat */
916+
0, /* sq_inplace_repeat */
917+
878918
};
879919

880920
/* deque object ********************************************************/

0 commit comments

Comments
 (0)