Skip to content

Commit

Permalink
bpo-39590: make deque.__contains__ and deque.count hold strong refere…
Browse files Browse the repository at this point in the history
…nces (GH-18421)
  • Loading branch information
sweeneyde committed Feb 9, 2020
1 parent 7f6f7ee commit c6dedde
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 0 deletions.
12 changes: 12 additions & 0 deletions Lib/test/test_deque.py
Expand Up @@ -183,6 +183,18 @@ def test_contains(self):
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)
Expand Down
@@ -0,0 +1 @@
Collections.deque now holds strong references during deque.__contains__ and deque.count, fixing crashes.
4 changes: 4 additions & 0 deletions Modules/_collectionsmodule.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit c6dedde

Please sign in to comment.