fix(asyncio): accept unsized iterables in as_completed

Since Python 3.12 asyncio.as_completed accepts a generator of awaitables,
but the tqdm wrapper calls len(fs) unconditionally when total is omitted,
so the same input raises TypeError: object of type 'generator' has no len().

Fall back to an unknown total when fs has no length, mirroring how
tqdm.std.tqdm.__init__ derives total from an iterable. Sized inputs keep
reporting their exact total, and an explicit total is still honoured.

Fixes #1811
This commit is contained in:
dualfroz committed 2026-09-03 14:12:03 +02:00
1 parent e80bb3a1e7
commit 8b30a4b77c
2 files changed
+24 -1

No files matched your search

+20
View File
@@ -120,6 +120,26 @@ async def test_as_completed(capsys, tol):
raise
@mark.asyncio
async def test_as_completed_unsized(capsys):
"""Test asyncio as_completed with an unsized iterable"""
fs = (asyncio.sleep(0, result=i) for i in range(3))
res = sorted([await f for f in as_completed(fs)])
assert res == [0, 1, 2]
_, err = capsys.readouterr()
assert '3it' in err
@mark.asyncio
async def test_as_completed_unsized_with_total(capsys):
"""Test asyncio as_completed with an unsized iterable and an explicit total"""
fs = (asyncio.sleep(0, result=i) for i in range(3))
res = sorted([await f for f in as_completed(fs, total=3)])
assert res == [0, 1, 2]
_, err = capsys.readouterr()
assert '3/3' in err
async def double(i):
return i * 2