From: Min RK Date: Wed, 15 Jun 2022 08:41:30 +0000 (+0200) Subject: Allow passing asyncio_loop argument to AsyncIOLoop X-Git-Tag: v6.2.0b2~3^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a86d3c774603c56a7f98c577da3694b777fcd10d;p=thirdparty%2Ftornado.git Allow passing asyncio_loop argument to AsyncIOLoop allows patterns of creating and explicitly passing the asyncio loop before creating IOLoop For example: creating a loop with the non-default event loop policy without having to set the current policy --- diff --git a/tornado/platform/asyncio.py b/tornado/platform/asyncio.py index 58d31ddd8..3b3678155 100644 --- a/tornado/platform/asyncio.py +++ b/tornado/platform/asyncio.py @@ -310,6 +310,12 @@ class AsyncIOLoop(BaseAsyncIOLoop): Each ``AsyncIOLoop`` creates a new ``asyncio.EventLoop``; this object can be accessed with the ``asyncio_loop`` attribute. + .. versionchanged:: 6.2 + + Support explicit ``asyncio_loop`` argument + for specifying the asyncio loop to attach to, + rather than always creating a new one with the default policy. + .. versionchanged:: 5.0 When an ``AsyncIOLoop`` becomes the current `.IOLoop`, it also sets @@ -323,13 +329,16 @@ class AsyncIOLoop(BaseAsyncIOLoop): def initialize(self, **kwargs: Any) -> None: # type: ignore self.is_current = False - loop = asyncio.new_event_loop() + loop = None + if "asyncio_loop" not in kwargs: + kwargs["asyncio_loop"] = loop = asyncio.new_event_loop() try: - super().initialize(loop, **kwargs) + super().initialize(**kwargs) except Exception: # If initialize() does not succeed (taking ownership of the loop), # we have to close it. - loop.close() + if loop is not None: + loop.close() raise def close(self, all_fds: bool = False) -> None: diff --git a/tornado/test/ioloop_test.py b/tornado/test/ioloop_test.py index 825f5a2a5..73ca32547 100644 --- a/tornado/test/ioloop_test.py +++ b/tornado/test/ioloop_test.py @@ -1,3 +1,4 @@ +import asyncio from concurrent.futures import ThreadPoolExecutor from concurrent import futures from collections.abc import Generator @@ -427,6 +428,12 @@ class TestIOLoop(AsyncTestCase): yield gen.multi([self.io_loop.run_in_executor(None, f) for i in range(2)]) + def test_explicit_asyncio_loop(self): + asyncio_loop = asyncio.new_event_loop() + loop = IOLoop(asyncio_loop=asyncio_loop, make_current=False) + assert loop.asyncio_loop is asyncio_loop # type: ignore + loop.close() + # Deliberately not a subclass of AsyncTestCase so the IOLoop isn't # automatically set as current.