Skip to content

Commit 9214e3f

Browse files
authored
gh-123471: Make itertools.zip_longest safe in the FT build (#146033)
1 parent 0de4e08 commit 9214e3f

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

Lib/test/test_free_threading/test_itertools.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import unittest
2-
from itertools import accumulate, batched, chain, combinations_with_replacement, cycle, permutations
2+
from itertools import accumulate, batched, chain, combinations_with_replacement, cycle, permutations, zip_longest
33
from test.support import threading_helper
44

55

@@ -62,6 +62,13 @@ def test_permutations(self):
6262
it = permutations(tuple(range(4)), 2)
6363
threading_helper.run_concurrently(work_iterator, nthreads=6, args=[it])
6464

65+
@threading_helper.reap_threads
66+
def test_zip_longest(self):
67+
number_of_iterations = 10
68+
for _ in range(number_of_iterations):
69+
it = zip_longest(list(range(4)), list(range(8)), fillvalue=0)
70+
threading_helper.run_concurrently(work_iterator, nthreads=10, args=[it])
71+
6572

6673
if __name__ == "__main__":
6774
unittest.main()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make concurrent iteration over :class:`itertools.zip_longest` safe under free-threading.

Modules/itertoolsmodule.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3876,7 +3876,7 @@ zip_longest_traverse(PyObject *op, visitproc visit, void *arg)
38763876
}
38773877

38783878
static PyObject *
3879-
zip_longest_next(PyObject *op)
3879+
zip_longest_next_lock_held(PyObject *op)
38803880
{
38813881
ziplongestobject *lz = ziplongestobject_CAST(op);
38823882
Py_ssize_t i;
@@ -3947,6 +3947,16 @@ zip_longest_next(PyObject *op)
39473947
return result;
39483948
}
39493949

3950+
static PyObject *
3951+
zip_longest_next(PyObject *op)
3952+
{
3953+
PyObject *result;
3954+
Py_BEGIN_CRITICAL_SECTION(op);
3955+
result = zip_longest_next_lock_held(op);
3956+
Py_END_CRITICAL_SECTION()
3957+
return result;
3958+
}
3959+
39503960
PyDoc_STRVAR(zip_longest_doc,
39513961
"zip_longest(*iterables, fillvalue=None)\n\
39523962
--\n\

0 commit comments

Comments
 (0)