Open
Description
Bug report
Bug description:
The enumerate object (and also the itertools.pairwise
since #118219) re-uses tuples when possible. It does this by checking the reference count to be 1:
// from enum_next in enumobject.c
if (Py_REFCNT(result) == 1) {
Py_INCREF(result);
old_index = PyTuple_GET_ITEM(result, 0);
old_item = PyTuple_GET_ITEM(result, 1);
PyTuple_SET_ITEM(result, 0, next_index);
PyTuple_SET_ITEM(result, 1, next_item);
Py_DECREF(old_index);
Py_DECREF(old_item);
....
The refcount check and increment are not atomic, so in the free-threading build multiple threads can end up operating on the result
object. It is possible that one thread already sets an item in the tuple, and another thread decrefs the item believing it is still an old item.
In the nogil reference implementation (https://github.com/colesbury/nogil) no changes are made to address this. So maybe the issue cannot occur?
In #120591 this problem is addressed with a lock, which might be too much overhead (see the discussion in #120496)
CPython versions tested on:
CPython main branch
Operating systems tested on:
Windows