mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
Issue #26194: Fix undefined behavior for deque.insert() when len(d) == maxlen
This commit is contained in:
parent
d4e51f45a9
commit
3743432302
4 changed files with 28 additions and 0 deletions
|
@ -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):
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue