Commit 37434323 authored by Raymond Hettinger's avatar Raymond Hettinger

Issue #26194: Fix undefined behavior for deque.insert() when len(d) == maxlen

parent d4e51f45
...@@ -477,6 +477,9 @@ or subtracting from an empty counter. ...@@ -477,6 +477,9 @@ or subtracting from an empty counter.
Insert *x* into the deque at position *i*. 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 .. versionadded:: 3.5
......
...@@ -304,6 +304,20 @@ class TestBasic(unittest.TestCase): ...@@ -304,6 +304,20 @@ class TestBasic(unittest.TestCase):
s.insert(i, 'Z') s.insert(i, 'Z')
self.assertEqual(list(d), s) 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): def test_imul(self):
for n in (-10, -1, 0, 1, 2, 10, 1000): for n in (-10, -1, 0, 1, 2, 10, 1000):
d = deque() d = deque()
......
...@@ -17,6 +17,10 @@ Core and Builtins ...@@ -17,6 +17,10 @@ Core and Builtins
Python 3.5.1 to hide the exact implementation of atomic C types, to avoid Python 3.5.1 to hide the exact implementation of atomic C types, to avoid
compiler issues. 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 - 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`` 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`` is now correctly compiled to two different functions: ``f1()`` returns ``1``
......
...@@ -973,10 +973,17 @@ deque_insert(dequeobject *deque, PyObject *args) ...@@ -973,10 +973,17 @@ deque_insert(dequeobject *deque, PyObject *args)
Py_ssize_t index; Py_ssize_t index;
Py_ssize_t n = Py_SIZE(deque); Py_ssize_t n = Py_SIZE(deque);
PyObject *value; PyObject *value;
PyObject *oldvalue;
PyObject *rv; PyObject *rv;
if (!PyArg_ParseTuple(args, "nO:insert", &index, &value)) if (!PyArg_ParseTuple(args, "nO:insert", &index, &value))
return NULL; 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) if (index >= n)
return deque_append(deque, value); return deque_append(deque, value);
if (index <= -n || index == 0) if (index <= -n || index == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment