https://github.com/python/cpython/commit/9214e3f33eeeb0ee862777378f98fdeb7b6944c6
commit: 9214e3f33eeeb0ee862777378f98fdeb7b6944c6
branch: main
author: Pieter Eendebak <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-03-27T19:31:49+05:30
summary:
gh-123471: Make `itertools.zip_longest` safe in the FT build (#146033)
files:
A Misc/NEWS.d/next/Library/2026-03-17-19-51-05.gh-issue-123471.oY4UR5.rst
M Lib/test/test_free_threading/test_itertools.py
M Modules/itertoolsmodule.c
diff --git a/Lib/test/test_free_threading/test_itertools.py
b/Lib/test/test_free_threading/test_itertools.py
index 20135dd3165acf..670d4ca8835e0d 100644
--- a/Lib/test/test_free_threading/test_itertools.py
+++ b/Lib/test/test_free_threading/test_itertools.py
@@ -1,5 +1,5 @@
import unittest
-from itertools import accumulate, batched, chain,
combinations_with_replacement, cycle, permutations
+from itertools import accumulate, batched, chain,
combinations_with_replacement, cycle, permutations, zip_longest
from test.support import threading_helper
@@ -62,6 +62,13 @@ def test_permutations(self):
it = permutations(tuple(range(4)), 2)
threading_helper.run_concurrently(work_iterator, nthreads=6,
args=[it])
+ @threading_helper.reap_threads
+ def test_zip_longest(self):
+ number_of_iterations = 10
+ for _ in range(number_of_iterations):
+ it = zip_longest(list(range(4)), list(range(8)), fillvalue=0)
+ threading_helper.run_concurrently(work_iterator, nthreads=10,
args=[it])
+
if __name__ == "__main__":
unittest.main()
diff --git
a/Misc/NEWS.d/next/Library/2026-03-17-19-51-05.gh-issue-123471.oY4UR5.rst
b/Misc/NEWS.d/next/Library/2026-03-17-19-51-05.gh-issue-123471.oY4UR5.rst
new file mode 100644
index 00000000000000..8d2e1b970e8171
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-03-17-19-51-05.gh-issue-123471.oY4UR5.rst
@@ -0,0 +1 @@
+Make concurrent iteration over :class:`itertools.zip_longest` safe under
free-threading.
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index 48f1d1c7fde17b..cf49724b8861c2 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -3876,7 +3876,7 @@ zip_longest_traverse(PyObject *op, visitproc visit, void
*arg)
}
static PyObject *
-zip_longest_next(PyObject *op)
+zip_longest_next_lock_held(PyObject *op)
{
ziplongestobject *lz = ziplongestobject_CAST(op);
Py_ssize_t i;
@@ -3947,6 +3947,16 @@ zip_longest_next(PyObject *op)
return result;
}
+static PyObject *
+zip_longest_next(PyObject *op)
+{
+ PyObject *result;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ result = zip_longest_next_lock_held(op);
+ Py_END_CRITICAL_SECTION()
+ return result;
+}
+
PyDoc_STRVAR(zip_longest_doc,
"zip_longest(*iterables, fillvalue=None)\n\
--\n\
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]