summaryrefslogtreecommitdiff
path: root/Lib/test/test_asyncio/test_tasks.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2021-04-25 13:40:44 +0300
committerGitHub <noreply@github.com>2021-04-25 13:40:44 +0300
commit172c0f2752d8708b6dda7b42e6c5a3519420a4e8 (patch)
tree35a076c6baad7ca053a62b9f505af3762a867b79 /Lib/test/test_asyncio/test_tasks.py
parentface87c94e67ad9c72b9a3724f112fd76c1002b9 (diff)
downloadcpython-git-172c0f2752d8708b6dda7b42e6c5a3519420a4e8.tar.gz
bpo-39529: Deprecate creating new event loop in asyncio.get_event_loop() (GH-23554)
asyncio.get_event_loop() emits now a deprecation warning when it creates a new event loop. In future releases it will became an alias of asyncio.get_running_loop().
Diffstat (limited to 'Lib/test/test_asyncio/test_tasks.py')
-rw-r--r--Lib/test/test_asyncio/test_tasks.py342
1 files changed, 231 insertions, 111 deletions
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index 7c2e85ceef..a9e4cf5356 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -200,22 +200,76 @@ class BaseTaskTests:
loop.close()
def test_ensure_future_coroutine(self):
+ async def notmuch():
+ return 'ok'
+ t = asyncio.ensure_future(notmuch(), loop=self.loop)
+ self.assertIs(t._loop, self.loop)
+ self.loop.run_until_complete(t)
+ self.assertTrue(t.done())
+ self.assertEqual(t.result(), 'ok')
+
+ a = notmuch()
+ self.addCleanup(a.close)
+ with self.assertWarns(DeprecationWarning) as cm:
+ with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
+ asyncio.ensure_future(a)
+ self.assertEqual(cm.warnings[0].filename, __file__)
+
+ async def test():
+ return asyncio.ensure_future(notmuch())
+ t = self.loop.run_until_complete(test())
+ self.assertIs(t._loop, self.loop)
+ self.loop.run_until_complete(t)
+ self.assertTrue(t.done())
+ self.assertEqual(t.result(), 'ok')
+
+ # Deprecated in 3.10
+ asyncio.set_event_loop(self.loop)
+ self.addCleanup(asyncio.set_event_loop, None)
+ with self.assertWarns(DeprecationWarning) as cm:
+ t = asyncio.ensure_future(notmuch())
+ self.assertEqual(cm.warnings[0].filename, __file__)
+ self.assertIs(t._loop, self.loop)
+ self.loop.run_until_complete(t)
+ self.assertTrue(t.done())
+ self.assertEqual(t.result(), 'ok')
+
+ def test_ensure_future_coroutine_2(self):
with self.assertWarns(DeprecationWarning):
@asyncio.coroutine
def notmuch():
return 'ok'
t = asyncio.ensure_future(notmuch(), loop=self.loop)
+ self.assertIs(t._loop, self.loop)
self.loop.run_until_complete(t)
self.assertTrue(t.done())
self.assertEqual(t.result(), 'ok')
+
+ a = notmuch()
+ self.addCleanup(a.close)
+ with self.assertWarns(DeprecationWarning) as cm:
+ with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
+ asyncio.ensure_future(a)
+ self.assertEqual(cm.warnings[0].filename, __file__)
+
+ async def test():
+ return asyncio.ensure_future(notmuch())
+ t = self.loop.run_until_complete(test())
self.assertIs(t._loop, self.loop)
+ self.loop.run_until_complete(t)
+ self.assertTrue(t.done())
+ self.assertEqual(t.result(), 'ok')
- loop = asyncio.new_event_loop()
- self.set_event_loop(loop)
- t = asyncio.ensure_future(notmuch(), loop=loop)
- self.assertIs(t._loop, loop)
- loop.run_until_complete(t)
- loop.close()
+ # Deprecated in 3.10
+ asyncio.set_event_loop(self.loop)
+ self.addCleanup(asyncio.set_event_loop, None)
+ with self.assertWarns(DeprecationWarning) as cm:
+ t = asyncio.ensure_future(notmuch())
+ self.assertEqual(cm.warnings[0].filename, __file__)
+ self.assertIs(t._loop, self.loop)
+ self.loop.run_until_complete(t)
+ self.assertTrue(t.done())
+ self.assertEqual(t.result(), 'ok')
def test_ensure_future_future(self):
f_orig = self.new_future(self.loop)
@@ -1078,33 +1132,6 @@ class BaseTaskTests:
res = loop.run_until_complete(asyncio.wait_for(coro(), timeout=None))
self.assertEqual(res, 'done')
- def test_wait_for_with_global_loop(self):
-
- def gen():
- when = yield
- self.assertAlmostEqual(0.2, when)
- when = yield 0
- self.assertAlmostEqual(0.01, when)
- yield 0.01
-
- loop = self.new_test_loop(gen)
-
- async def foo():
- await asyncio.sleep(0.2)
- return 'done'
-
- asyncio.set_event_loop(loop)
- try:
- fut = self.new_task(loop, foo())
- with self.assertRaises(asyncio.TimeoutError):
- loop.run_until_complete(asyncio.wait_for(fut, 0.01))
- finally:
- asyncio.set_event_loop(None)
-
- self.assertAlmostEqual(0.01, loop.time())
- self.assertTrue(fut.done())
- self.assertTrue(fut.cancelled())
-
def test_wait_for_race_condition(self):
def gen():
@@ -1293,32 +1320,6 @@ class BaseTaskTests:
self.assertAlmostEqual(0.15, loop.time())
self.assertEqual(res, 42)
- def test_wait_with_global_loop(self):
-
- def gen():
- when = yield
- self.assertAlmostEqual(0.01, when)
- when = yield 0
- self.assertAlmostEqual(0.015, when)
- yield 0.015
-
- loop = self.new_test_loop(gen)
-
- a = self.new_task(loop, asyncio.sleep(0.01))
- b = self.new_task(loop, asyncio.sleep(0.015))
-
- async def foo():
- done, pending = await asyncio.wait([b, a])
- self.assertEqual(done, set([a, b]))
- self.assertEqual(pending, set())
- return 42
-
- asyncio.set_event_loop(loop)
- res = loop.run_until_complete(
- self.new_task(loop, foo()))
-
- self.assertEqual(res, 42)
-
def test_wait_duplicate_coroutines(self):
with self.assertWarns(DeprecationWarning):
@@ -1679,22 +1680,24 @@ class BaseTaskTests:
yield 0
loop = self.new_test_loop(gen)
- asyncio.set_event_loop(loop)
a = asyncio.sleep(0.05, 'a')
b = asyncio.sleep(0.10, 'b')
fs = {a, b}
- futs = list(asyncio.as_completed(fs))
- self.assertEqual(len(futs), 2)
+ async def test():
+ futs = list(asyncio.as_completed(fs))
+ self.assertEqual(len(futs), 2)
+
+ x = await futs[1]
+ self.assertEqual(x, 'a')
+ self.assertAlmostEqual(0.05, loop.time())
+ loop.advance_time(0.05)
+ y = await futs[0]
+ self.assertEqual(y, 'b')
+ self.assertAlmostEqual(0.10, loop.time())
- x = loop.run_until_complete(futs[1])
- self.assertEqual(x, 'a')
- self.assertAlmostEqual(0.05, loop.time())
- loop.advance_time(0.05)
- y = loop.run_until_complete(futs[0])
- self.assertEqual(y, 'b')
- self.assertAlmostEqual(0.10, loop.time())
+ loop.run_until_complete(test())
def test_as_completed_concurrent(self):
@@ -1705,20 +1708,22 @@ class BaseTaskTests:
self.assertAlmostEqual(0.05, when)
yield 0.05
- loop = self.new_test_loop(gen)
- asyncio.set_event_loop(loop)
-
a = asyncio.sleep(0.05, 'a')
b = asyncio.sleep(0.05, 'b')
fs = {a, b}
- futs = list(asyncio.as_completed(fs))
- self.assertEqual(len(futs), 2)
- waiter = asyncio.wait(futs)
- # Deprecation from passing coros in futs to asyncio.wait()
- with self.assertWarns(DeprecationWarning):
- done, pending = loop.run_until_complete(waiter)
- self.assertEqual(set(f.result() for f in done), {'a', 'b'})
+ async def test():
+ futs = list(asyncio.as_completed(fs))
+ self.assertEqual(len(futs), 2)
+ waiter = asyncio.wait(futs)
+ # Deprecation from passing coros in futs to asyncio.wait()
+ with self.assertWarns(DeprecationWarning) as cm:
+ done, pending = await waiter
+ self.assertEqual(cm.warnings[0].filename, __file__)
+ self.assertEqual(set(f.result() for f in done), {'a', 'b'})
+
+ loop = self.new_test_loop(gen)
+ loop.run_until_complete(test())
def test_as_completed_duplicate_coroutines(self):
@@ -1742,6 +1747,47 @@ class BaseTaskTests:
self.assertEqual(set(result), {'ham', 'spam'})
self.assertEqual(len(result), 2)
+ def test_as_completed_coroutine_without_loop(self):
+ async def coro():
+ return 42
+
+ a = coro()
+ self.addCleanup(a.close)
+
+ futs = asyncio.as_completed([a])
+ with self.assertWarns(DeprecationWarning) as cm:
+ with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
+ list(futs)
+ self.assertEqual(cm.warnings[0].filename, __file__)
+
+ def test_as_completed_coroutine_use_running_loop(self):
+ loop = self.new_test_loop()
+
+ async def coro():
+ return 42
+
+ async def test():
+ futs = list(asyncio.as_completed([coro()]))
+ self.assertEqual(len(futs), 1)
+ self.assertEqual(await futs[0], 42)
+
+ loop.run_until_complete(test())
+
+ def test_as_completed_coroutine_use_global_loop(self):
+ # Deprecated in 3.10
+ async def coro():
+ return 42
+
+ loop = self.new_test_loop()
+ asyncio.set_event_loop(loop)
+ self.addCleanup(asyncio.set_event_loop, None)
+ futs = asyncio.as_completed([coro()])
+ with self.assertWarns(DeprecationWarning) as cm:
+ futs = list(futs)
+ self.assertEqual(cm.warnings[0].filename, __file__)
+ self.assertEqual(len(futs), 1)
+ self.assertEqual(loop.run_until_complete(futs[0]), 42)
+
def test_sleep(self):
def gen():
@@ -2201,6 +2247,42 @@ class BaseTaskTests:
child2.set_result(2)
test_utils.run_briefly(self.loop)
+ def test_shield_coroutine_without_loop(self):
+ async def coro():
+ return 42
+
+ inner = coro()
+ self.addCleanup(inner.close)
+ with self.assertWarns(DeprecationWarning) as cm:
+ with self.assertRaisesRegex(RuntimeError, 'There is no current event loop'):
+ asyncio.shield(inner)
+ self.assertEqual(cm.warnings[0].filename, __file__)
+
+ def test_shield_coroutine_use_running_loop(self):
+ async def coro():
+ return 42
+
+ async def test():
+ return asyncio.shield(coro())
+ outer = self.loop.run_until_complete(test())
+ self.assertEqual(outer._loop, self.loop)
+ res = self.loop.run_until_complete(outer)
+ self.assertEqual(res, 42)
+
+ def test_shield_coroutine_use_global_loop(self):
+ # Deprecated in 3.10
+ async def coro():
+ return 42
+
+ asyncio.set_event_loop(self.loop)
+ self.addCleanup(asyncio.set_event_loop, None)
+ with self.assertWarns(DeprecationWarning) as cm:
+ outer = asyncio.shield(coro())
+ self.assertEqual(cm.warnings[0].filename, __file__)
+ self.assertEqual(outer._loop, self.loop)
+ res = self.loop.run_until_complete(outer)
+ self.assertEqual(res, 42)
+
def test_as_completed_invalid_args(self):
fut = self.new_future(self.loop)
@@ -2507,16 +2589,17 @@ class BaseTaskTests:
"""Ensure that a gathering future refuses to be cancelled once all
children are done"""
loop = asyncio.new_event_loop()
- asyncio.set_event_loop(loop)
self.addCleanup(loop.close)
fut = self.new_future(loop)
- # The indirection fut->child_coro is needed since otherwise the
- # gathering task is done at the same time as the child future
- def child_coro():
- return (yield from fut)
- gather_future = asyncio.gather(child_coro())
- gather_task = asyncio.ensure_future(gather_future, loop=loop)
+ async def create():
+ # The indirection fut->child_coro is needed since otherwise the
+ # gathering task is done at the same time as the child future
+ def child_coro():
+ return (yield from fut)
+ gather_future = asyncio.gather(child_coro())
+ return asyncio.ensure_future(gather_future)
+ gather_task = loop.run_until_complete(create())
cancel_result = None
def cancelling_callback(_):
@@ -3222,7 +3305,7 @@ class GatherTestsBase:
def _check_success(self, **kwargs):
a, b, c = [self.one_loop.create_future() for i in range(3)]
- fut = asyncio.gather(*self.wrap_futures(a, b, c), **kwargs)
+ fut = self._gather(*self.wrap_futures(a, b, c), **kwargs)
cb = test_utils.MockCallback()
fut.add_done_callback(cb)
b.set_result(1)
@@ -3244,7 +3327,7 @@ class GatherTestsBase:
def test_one_exception(self):
a, b, c, d, e = [self.one_loop.create_future() for i in range(5)]
- fut = asyncio.gather(*self.wrap_futures(a, b, c, d, e))
+ fut = self._gather(*self.wrap_futures(a, b, c, d, e))
cb = test_utils.MockCallback()
fut.add_done_callback(cb)
exc = ZeroDivisionError()
@@ -3262,8 +3345,8 @@ class GatherTestsBase:
def test_return_exceptions(self):
a, b, c, d = [self.one_loop.create_future() for i in range(4)]
- fut = asyncio.gather(*self.wrap_futures(a, b, c, d),
- return_exceptions=True)
+ fut = self._gather(*self.wrap_futures(a, b, c, d),
+ return_exceptions=True)
cb = test_utils.MockCallback()
fut.add_done_callback(cb)
exc = ZeroDivisionError()
@@ -3315,22 +3398,38 @@ class FutureGatherTests(GatherTestsBase, test_utils.TestCase):
def wrap_futures(self, *futures):
return futures
- def _check_empty_sequence(self, seq_or_iter):
+ def _gather(self, *args, **kwargs):
+ return asyncio.gather(*args, **kwargs)
+
+ def test_constructor_empty_sequence_without_loop(self):
+ with self.assertWarns(DeprecationWarning) as cm:
+ with self.assertRaises(RuntimeError):
+ asyncio.gather()
+ self.assertEqual(cm.warnings[0].filename, __file__)
+
+ def test_constructor_empty_sequence_use_running_loop(self):
+ async def gather():
+ return asyncio.gather()
+ fut = self.one_loop.run_until_complete(gather())
+ self.assertIsInstance(fut, asyncio.Future)
+ self.assertIs(fut._loop, self.one_loop)
+ self._run_loop(self.one_loop)
+ self.assertTrue(fut.done())
+ self.assertEqual(fut.result(), [])
+
+ def test_constructor_empty_sequence_use_global_loop(self):
+ # Deprecated in 3.10
asyncio.set_event_loop(self.one_loop)
self.addCleanup(asyncio.set_event_loop, None)
- fut = asyncio.gather(*seq_or_iter)
+ with self.assertWarns(DeprecationWarning) as cm:
+ fut = asyncio.gather()
+ self.assertEqual(cm.warnings[0].filename, __file__)
self.assertIsInstance(fut, asyncio.Future)
self.assertIs(fut._loop, self.one_loop)
self._run_loop(self.one_loop)
self.assertTrue(fut.done())
self.assertEqual(fut.result(), [])
- def test_constructor_empty_sequence(self):
- self._check_empty_sequence([])
- self._check_empty_sequence(())
- self._check_empty_sequence(set())
- self._check_empty_sequence(iter(""))
-
def test_constructor_heterogenous_futures(self):
fut1 = self.one_loop.create_future()
fut2 = self.other_loop.create_future()
@@ -3392,10 +3491,6 @@ class FutureGatherTests(GatherTestsBase, test_utils.TestCase):
class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
- def setUp(self):
- super().setUp()
- asyncio.set_event_loop(self.one_loop)
-
def wrap_futures(self, *futures):
coros = []
for fut in futures:
@@ -3404,22 +3499,47 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
coros.append(coro())
return coros
- def test_constructor_loop_selection(self):
+ def _gather(self, *args, **kwargs):
+ async def coro():
+ return asyncio.gather(*args, **kwargs)
+ return self.one_loop.run_until_complete(coro())
+
+ def test_constructor_without_loop(self):
async def coro():
return 'abc'
gen1 = coro()
+ self.addCleanup(gen1.close)
gen2 = coro()
- fut = asyncio.gather(gen1, gen2)
+ self.addCleanup(gen2.close)
+ with self.assertWarns(DeprecationWarning) as cm:
+ with self.assertRaises(RuntimeError):
+ asyncio.gather(gen1, gen2)
+ self.assertEqual(cm.warnings[0].filename, __file__)
+
+ def test_constructor_use_running_loop(self):
+ async def coro():
+ return 'abc'
+ gen1 = coro()
+ gen2 = coro()
+ async def gather():
+ return asyncio.gather(gen1, gen2)
+ fut = self.one_loop.run_until_complete(gather())
self.assertIs(fut._loop, self.one_loop)
self.one_loop.run_until_complete(fut)
- self.set_event_loop(self.other_loop, cleanup=False)
+ def test_constructor_use_global_loop(self):
+ # Deprecated in 3.10
+ async def coro():
+ return 'abc'
asyncio.set_event_loop(self.other_loop)
- gen3 = coro()
- gen4 = coro()
- fut2 = asyncio.gather(gen3, gen4)
- self.assertIs(fut2._loop, self.other_loop)
- self.other_loop.run_until_complete(fut2)
+ self.addCleanup(asyncio.set_event_loop, None)
+ gen1 = coro()
+ gen2 = coro()
+ with self.assertWarns(DeprecationWarning) as cm:
+ fut = asyncio.gather(gen1, gen2)
+ self.assertEqual(cm.warnings[0].filename, __file__)
+ self.assertIs(fut._loop, self.other_loop)
+ self.other_loop.run_until_complete(fut)
def test_duplicate_coroutines(self):
with self.assertWarns(DeprecationWarning):
@@ -3427,7 +3547,7 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase):
def coro(s):
return s
c = coro('abc')
- fut = asyncio.gather(c, c, coro('def'), c)
+ fut = self._gather(c, c, coro('def'), c)
self._run_loop(self.one_loop)
self.assertEqual(fut.result(), ['abc', 'abc', 'def', 'abc'])