Skip to content

Commit

Permalink
bpo-42140: Improve asyncio.wait function (GH-22938)
Browse files Browse the repository at this point in the history
GH- Improve asyncio.wait function

The original code creates the futures set two times.
We can create this set before, avoiding the second creation.

This new behaviour [breaks the aiokafka library](aio-libs/aiokafka#672), because it gives an iterator to that function, so the second iteration become empty.

Automerge-Triggered-By: GH:1st1
(cherry picked from commit 7e5ef0a)

Co-authored-by: Diogo Dutra <diogodutradamata@gmail.com>
  • Loading branch information
miss-islington and dutradda authored Nov 10, 2020
1 parent f8bea0a commit 33922cb
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
6 changes: 4 additions & 2 deletions Lib/asyncio/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,13 +400,15 @@ async def wait(fs, *, loop=None, timeout=None, return_when=ALL_COMPLETED):
"and scheduled for removal in Python 3.10.",
DeprecationWarning, stacklevel=2)

if any(coroutines.iscoroutine(f) for f in set(fs)):
fs = set(fs)

if any(coroutines.iscoroutine(f) for f in fs):
warnings.warn("The explicit passing of coroutine objects to "
"asyncio.wait() is deprecated since Python 3.8, and "
"scheduled for removal in Python 3.11.",
DeprecationWarning, stacklevel=2)

fs = {ensure_future(f, loop=loop) for f in set(fs)}
fs = {ensure_future(f, loop=loop) for f in fs}

return await _wait(fs, timeout, return_when, loop)

Expand Down
24 changes: 24 additions & 0 deletions Lib/test/test_asyncio/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,30 @@ def gen():
loop.advance_time(10)
loop.run_until_complete(asyncio.wait([a, b]))

def test_wait_with_iterator_of_tasks(self):

def gen():
when = yield
self.assertAlmostEqual(0.1, when)
when = yield 0
self.assertAlmostEqual(0.15, when)
yield 0.15

loop = self.new_test_loop(gen)

a = self.new_task(loop, asyncio.sleep(0.1))
b = self.new_task(loop, asyncio.sleep(0.15))

async def foo():
done, pending = await asyncio.wait(iter([b, a]))
self.assertEqual(done, set([a, b]))
self.assertEqual(pending, set())
return 42

res = loop.run_until_complete(self.new_task(loop, foo()))
self.assertEqual(res, 42)
self.assertAlmostEqual(0.15, loop.time())

def test_as_completed(self):

def gen():
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improve asyncio.wait function to create the futures set just one time.

0 comments on commit 33922cb

Please sign in to comment.