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:
1 parent
e80bb3a1e7
commit
8b30a4b77c
2 files changed
+23
No files matched your search
@@ -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
|
||||
|
||||
|
||||
@@ -64,7 +64,10 @@ class tqdm_asyncio(std_tqdm):
|
||||
Wrapper for `asyncio.as_completed`.
|
||||
"""
|
||||
if total is None:
|
||||
try:
|
||||
total = len(fs)
|
||||
except (TypeError, AttributeError):
|
||||
total = None
|
||||
kwargs = {}
|
||||
if version_info[:2] < (3, 10):
|
||||
kwargs['loop'] = loop
|
||||
|
||||
Reference in new issue
Block a user