changeset: 100072:ce3d47eaeb21 branch: 3.5 parent: 100066:8571355e62ff user: Raymond Hettinger date: Tue Jan 26 21:44:16 2016 -0800 files: Doc/library/collections.rst Lib/test/test_deque.py Misc/NEWS Modules/_collectionsmodule.c description: Issue #26194: Fix undefined behavior for deque.insert() when len(d) == maxlen diff -r 8571355e62ff -r ce3d47eaeb21 Doc/library/collections.rst --- a/Doc/library/collections.rst Mon Jan 25 18:53:34 2016 -0800 +++ b/Doc/library/collections.rst Tue Jan 26 21:44:16 2016 -0800 @@ -477,6 +477,9 @@ Insert *x* into the deque at position *i*. + If the insertion causes a bounded deque to grow beyond *maxlen*, the + rightmost element is then removed to restore the size limit. + .. versionadded:: 3.5 diff -r 8571355e62ff -r ce3d47eaeb21 Lib/test/test_deque.py --- a/Lib/test/test_deque.py Mon Jan 25 18:53:34 2016 -0800 +++ b/Lib/test/test_deque.py Tue Jan 26 21:44:16 2016 -0800 @@ -304,6 +304,20 @@ s.insert(i, 'Z') self.assertEqual(list(d), s) + def test_index_bug_26194(self): + data = 'ABC' + for i in range(len(data) + 1): + d = deque(data, len(data)) + d.insert(i, None) + s = list(data) + s.insert(i, None) + s.pop() + self.assertEqual(list(d), s) + if i < len(data): + self.assertIsNone(d[i]) + else: + self.assertTrue(None not in d) + def test_imul(self): for n in (-10, -1, 0, 1, 2, 10, 1000): d = deque() diff -r 8571355e62ff -r ce3d47eaeb21 Misc/NEWS --- a/Misc/NEWS Mon Jan 25 18:53:34 2016 -0800 +++ b/Misc/NEWS Tue Jan 26 21:44:16 2016 -0800 @@ -17,6 +17,10 @@ Python 3.5.1 to hide the exact implementation of atomic C types, to avoid compiler issues. +- Issue #26194: Deque.insert() gave odd results for bounded deques that had + reached their maximum size. Now, the insert will happen normally and then + any overflowing element will be truncated from the right side. + - Issue #25843: When compiling code, don't merge constants if they are equal but have a different types. For example, ``f1, f2 = lambda: 1, lambda: 1.0`` is now correctly compiled to two different functions: ``f1()`` returns ``1`` diff -r 8571355e62ff -r ce3d47eaeb21 Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c Mon Jan 25 18:53:34 2016 -0800 +++ b/Modules/_collectionsmodule.c Tue Jan 26 21:44:16 2016 -0800 @@ -973,10 +973,17 @@ Py_ssize_t index; Py_ssize_t n = Py_SIZE(deque); PyObject *value; + PyObject *oldvalue; PyObject *rv; if (!PyArg_ParseTuple(args, "nO:insert", &index, &value)) return NULL; + if (deque->maxlen == Py_SIZE(deque)) { + if (index >= deque->maxlen || Py_SIZE(deque) == 0) + Py_RETURN_NONE; + oldvalue = deque_pop(deque, NULL); + Py_DECREF(oldvalue); + } if (index >= n) return deque_append(deque, value); if (index <= -n || index == 0)