Fix variants of deque.extend: d.extend(d) d+=d d.extendleft(d)

This commit is contained in:
Raymond Hettinger 2009-12-10 03:03:02 +00:00
parent 0f6cae0bff
commit 3f9afd816d
3 changed files with 53 additions and 0 deletions

View 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))))

View File

@ -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.

View 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 ********************************************************/