bpo-39590: make deque.__contains__ and deque.count hold strong references (GH-18421)

This commit is contained in:
sweeneyde 2020-02-09 03:16:43 -05:00 committed by GitHub
parent 7f6f7eef52
commit c6dedde160
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 0 deletions

View File

@ -183,6 +183,18 @@ class TestBasic(unittest.TestCase):
with self.assertRaises(RuntimeError):
n in d
def test_contains_count_stop_crashes(self):
class A:
def __eq__(self, other):
d.clear()
return NotImplemented
d = deque([A(), A()])
with self.assertRaises(RuntimeError):
_ = 3 in d
d = deque([A(), A()])
with self.assertRaises(RuntimeError):
_ = d.count(3)
def test_extend(self):
d = deque('a')
self.assertRaises(TypeError, d.extend, 1)

View File

@ -0,0 +1 @@
Collections.deque now holds strong references during deque.__contains__ and deque.count, fixing crashes.

View File

@ -965,7 +965,9 @@ deque_count(dequeobject *deque, PyObject *v)
while (--n >= 0) {
CHECK_NOT_END(b);
item = b->data[index];
Py_INCREF(item);
cmp = PyObject_RichCompareBool(item, v, Py_EQ);
Py_DECREF(item);
if (cmp < 0)
return NULL;
count += cmp;
@ -1002,7 +1004,9 @@ deque_contains(dequeobject *deque, PyObject *v)
while (--n >= 0) {
CHECK_NOT_END(b);
item = b->data[index];
Py_INCREF(item);
cmp = PyObject_RichCompareBool(item, v, Py_EQ);
Py_DECREF(item);
if (cmp) {
return cmp;
}