def test_asyncio_adapter(self): # This test demonstrates that when using the asyncio coroutine # runner (i.e. run_until_complete), the to_asyncio_future # adapter is needed. No adapter is needed in the other direction, # as demonstrated by other tests in the package. @gen.coroutine def tornado_coroutine(): yield gen.Task(self.io_loop.add_callback) raise gen.Return(42) native_coroutine_without_adapter = exec_test(globals(), locals(), """ async def native_coroutine_without_adapter(): return await tornado_coroutine() """)["native_coroutine_without_adapter"] native_coroutine_with_adapter = exec_test(globals(), locals(), """ async def native_coroutine_with_adapter(): return await to_asyncio_future(tornado_coroutine()) """)["native_coroutine_with_adapter"] # Use the adapter, but two degrees from the tornado coroutine. native_coroutine_with_adapter2 = exec_test(globals(), locals(), """ async def native_coroutine_with_adapter2(): return await to_asyncio_future(native_coroutine_without_adapter()) """)["native_coroutine_with_adapter2"] # Tornado supports native coroutines both with and without adapters self.assertEqual( self.io_loop.run_sync(native_coroutine_without_adapter), 42) self.assertEqual( self.io_loop.run_sync(native_coroutine_with_adapter), 42) self.assertEqual( self.io_loop.run_sync(native_coroutine_with_adapter2), 42) # Asyncio only supports coroutines that yield asyncio-compatible # Futures (which our Future is since 5.0). self.assertEqual( asyncio.get_event_loop().run_until_complete( native_coroutine_without_adapter()), 42) self.assertEqual( asyncio.get_event_loop().run_until_complete( native_coroutine_with_adapter()), 42) self.assertEqual( asyncio.get_event_loop().run_until_complete( native_coroutine_with_adapter2()), 42)
def test_asyncio_adapter(self): # This test demonstrates that when using the asyncio coroutine # runner (i.e. run_until_complete), the to_asyncio_future # adapter is needed. No adapter is needed in the other direction, # as demonstrated by other tests in the package. @gen.coroutine def tornado_coroutine(): yield gen.Task(self.io_loop.add_callback) raise gen.Return(42) native_coroutine_without_adapter = exec_test(globals(), locals(), """ async def native_coroutine_without_adapter(): return await tornado_coroutine() """)["native_coroutine_without_adapter"] native_coroutine_with_adapter = exec_test(globals(), locals(), """ async def native_coroutine_with_adapter(): return await to_asyncio_future(tornado_coroutine()) """)["native_coroutine_with_adapter"] # Use the adapter, but two degrees from the tornado coroutine. native_coroutine_with_adapter2 = exec_test(globals(), locals(), """ async def native_coroutine_with_adapter2(): return await to_asyncio_future(native_coroutine_without_adapter()) """)["native_coroutine_with_adapter2"] # Tornado supports native coroutines both with and without adapters self.assertEqual( self.io_loop.run_sync(native_coroutine_without_adapter), 42) self.assertEqual( self.io_loop.run_sync(native_coroutine_with_adapter), 42) self.assertEqual( self.io_loop.run_sync(native_coroutine_with_adapter2), 42) # Asyncio only supports coroutines that yield asyncio-compatible # Futures. with self.assertRaises(RuntimeError): asyncio.get_event_loop().run_until_complete( native_coroutine_without_adapter()) self.assertEqual( asyncio.get_event_loop().run_until_complete( native_coroutine_with_adapter()), 42) self.assertEqual( asyncio.get_event_loop().run_until_complete( native_coroutine_with_adapter2()), 42)
def get_and_close_event_loop(): """Get the event loop. Close it if one is returned. Returns the (closed) event loop. This is a silly thing to do and leaves the thread in a broken state, but it's enough for this test. Closing the loop avoids resource leak warnings. """ loop = asyncio.get_event_loop() loop.close() return loop
def run_policy_test(self, accessor, expected_type): # With the default policy, non-main threads don't get an event # loop. self.assertRaises(RuntimeError, self.executor.submit(accessor).result) # Set the policy and we can get a loop. asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy()) self.assertIsInstance( self.executor.submit(accessor).result(), expected_type) # Clean up to silence leak warnings. Always use asyncio since # IOLoop doesn't (currently) close the underlying loop. self.executor.submit(lambda: asyncio.get_event_loop().close()).result()
def test_asyncio_future(self): # Test that we can yield an asyncio future from a tornado coroutine. # Without 'yield from', we must wrap coroutines in ensure_future, # which was introduced during Python 3.4, deprecating the prior "async". if hasattr(asyncio, 'ensure_future'): ensure_future = asyncio.ensure_future else: ensure_future = asyncio. async x = yield ensure_future(asyncio.get_event_loop().run_in_executor( None, lambda: 42)) self.assertEqual(x, 42)
def test_asyncio_future(self): # Test that we can yield an asyncio future from a tornado coroutine. # Without 'yield from', we must wrap coroutines in ensure_future, # which was introduced during Python 3.4, deprecating the prior "async". if hasattr(asyncio, 'ensure_future'): ensure_future = asyncio.ensure_future else: ensure_future = asyncio.async x = yield ensure_future( asyncio.get_event_loop().run_in_executor(None, lambda: 42)) self.assertEqual(x, 42)
def test_asyncio_callback(self): # Basic test that the asyncio loop is set up correctly. asyncio.get_event_loop().call_soon(self.stop) self.wait()
def tearDown(self): asyncio.get_event_loop().close() asyncio.set_event_loop_policy(self.orig_policy)
def test_asyncio_future(self): # Test that we can yield an asyncio future from a tornado coroutine. # Without 'yield from', we must wrap coroutines in asyncio.async. x = yield asyncio. async (asyncio.get_event_loop().run_in_executor( None, lambda: 42)) self.assertEqual(x, 42)
def test_asyncio_future(self): # Test that we can yield an asyncio future from a tornado coroutine. # Without 'yield from', we must wrap coroutines in asyncio.async. x = yield asyncio.async( asyncio.get_event_loop().run_in_executor(None, lambda: 42)) self.assertEqual(x, 42)