mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
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().
This commit is contained in:
parent
face87c94e
commit
172c0f2752
16 changed files with 570 additions and 185 deletions
|
@ -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')
|
||||
self.assertIs(t._loop, self.loop)
|
||||
|
||||
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()
|
||||
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_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 = 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())
|
||||
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())
|
||||
|
||||
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,21 +3398,37 @@ class FutureGatherTests(GatherTestsBase, test_utils.TestCase):
|
|||
def wrap_futures(self, *futures):
|
||||
return futures
|
||||
|
||||
def _check_empty_sequence(self, seq_or_iter):
|
||||
asyncio.set_event_loop(self.one_loop)
|
||||
self.addCleanup(asyncio.set_event_loop, None)
|
||||
fut = asyncio.gather(*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(self):
|
||||
self._check_empty_sequence([])
|
||||
self._check_empty_sequence(())
|
||||
self._check_empty_sequence(set())
|
||||
self._check_empty_sequence(iter(""))
|
||||
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)
|
||||
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_heterogenous_futures(self):
|
||||
fut1 = self.one_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()
|
||||
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()
|
||||
fut = asyncio.gather(gen1, gen2)
|
||||
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'])
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue