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

Skip to content

Commit 3743432

Browse files
committed
Issue #26194: Fix undefined behavior for deque.insert() when len(d) == maxlen
1 parent d4e51f4 commit 3743432

4 files changed

Lines changed: 28 additions & 0 deletions

File tree

Doc/library/collections.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,9 @@ or subtracting from an empty counter.
477477

478478
Insert *x* into the deque at position *i*.
479479

480+
If the insertion causes a bounded deque to grow beyond *maxlen*, the
481+
rightmost element is then removed to restore the size limit.
482+
480483
.. versionadded:: 3.5
481484

482485

Lib/test/test_deque.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,20 @@ def test_insert(self):
304304
s.insert(i, 'Z')
305305
self.assertEqual(list(d), s)
306306

307+
def test_index_bug_26194(self):
308+
data = 'ABC'
309+
for i in range(len(data) + 1):
310+
d = deque(data, len(data))
311+
d.insert(i, None)
312+
s = list(data)
313+
s.insert(i, None)
314+
s.pop()
315+
self.assertEqual(list(d), s)
316+
if i < len(data):
317+
self.assertIsNone(d[i])
318+
else:
319+
self.assertTrue(None not in d)
320+
307321
def test_imul(self):
308322
for n in (-10, -1, 0, 1, 2, 10, 1000):
309323
d = deque()

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ Core and Builtins
1717
Python 3.5.1 to hide the exact implementation of atomic C types, to avoid
1818
compiler issues.
1919

20+
- Issue #26194: Deque.insert() gave odd results for bounded deques that had
21+
reached their maximum size. Now, the insert will happen normally and then
22+
any overflowing element will be truncated from the right side.
23+
2024
- Issue #25843: When compiling code, don't merge constants if they are equal
2125
but have a different types. For example, ``f1, f2 = lambda: 1, lambda: 1.0``
2226
is now correctly compiled to two different functions: ``f1()`` returns ``1``

Modules/_collectionsmodule.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,10 +973,17 @@ deque_insert(dequeobject *deque, PyObject *args)
973973
Py_ssize_t index;
974974
Py_ssize_t n = Py_SIZE(deque);
975975
PyObject *value;
976+
PyObject *oldvalue;
976977
PyObject *rv;
977978

978979
if (!PyArg_ParseTuple(args, "nO:insert", &index, &value))
979980
return NULL;
981+
if (deque->maxlen == Py_SIZE(deque)) {
982+
if (index >= deque->maxlen || Py_SIZE(deque) == 0)
983+
Py_RETURN_NONE;
984+
oldvalue = deque_pop(deque, NULL);
985+
Py_DECREF(oldvalue);
986+
}
980987
if (index >= n)
981988
return deque_append(deque, value);
982989
if (index <= -n || index == 0)

0 commit comments

Comments
 (0)