From 38234a37024bd01b19ad058cb1e0851203d61658 Mon Sep 17 00:00:00 2001 From: fhgffy <102001626+fhgffy@users.noreply.github.com> Date: Fri, 2 Oct 2026 05:55:02 -0700 Subject: [PATCH] Fix interleave data loss with shared iterators --- toolz/itertoolz.py | 3 ++- toolz/tests/test_itertoolz.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/toolz/itertoolz.py b/toolz/itertoolz.py index 05c36cca..439a06dd 100644 --- a/toolz/itertoolz.py +++ b/toolz/itertoolz.py @@ -228,7 +228,8 @@ def interleave(seqs): Returns a lazy iterator """ - iters = itertools.cycle(map(iter, seqs)) + # Distinguish occurrences of the same iterator when removing a slot. + iters = itertools.cycle(map(itertools.chain, seqs)) while True: try: for itr in iters: diff --git a/toolz/tests/test_itertoolz.py b/toolz/tests/test_itertoolz.py index d20da2b8..60e944c3 100644 --- a/toolz/tests/test_itertoolz.py +++ b/toolz/tests/test_itertoolz.py @@ -99,6 +99,37 @@ def test_interleave(): assert ''.join(interleave(('ABC', '1'))) == 'A1BC' +def test_interleave_shared_iterator(): + shared = iter([0, 1]) + assert list(interleave([shared, shared, [10, 11]])) == [0, 1, 10, 11] + + shared = iter([0, 1]) + assert list(interleave([shared, [10, 11], shared, [20, 21]])) == [ + 0, 10, 1, 20, 11, 21] + + shared = iter([0, 1, 2]) + assert list(interleave([shared, shared, [10, 11]])) == [0, 1, 10, 2, 11] + + +def test_interleave_shared_empty_iterator(): + shared = iter([]) + assert list(interleave([shared, shared, [10, 11]])) == [10, 11] + + shared = iter([]) + assert list(interleave([shared, shared])) == [] + assert list(interleave([])) == [] + + +def test_interleave_shared_iterator_with_infinite_input(): + shared = iter([0, 1]) + result = interleave([shared, shared, itertools.count(10)]) + assert list(take(6, result)) == [0, 1, 10, 11, 12, 13] + + shared = iter([]) + seqs = itertools.chain([shared, shared], ([n] for n in itertools.count())) + assert list(take(4, interleave(seqs))) == [0, 1, 2, 3] + + def test_unique(): assert tuple(unique((1, 2, 3))) == (1, 2, 3) assert tuple(unique((1, 2, 1, 3))) == (1, 2, 3)