]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Allow passing asyncio_loop argument to AsyncIOLoop
authorMin RK <benjaminrk@gmail.com>
Wed, 15 Jun 2022 08:41:30 +0000 (10:41 +0200)
committerMin RK <benjaminrk@gmail.com>
Wed, 15 Jun 2022 11:43:50 +0000 (13:43 +0200)
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

tornado/platform/asyncio.py
tornado/test/ioloop_test.py

index 58d31ddd8158e7cdcbb244ccc7cc48073ae03ca3..3b3678155bec935ff970b400a1b65a2f4a7714be 100644 (file)
@@ -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:
index 825f5a2a5323f34637039d81c2814c9dee3cdb67..73ca3254712ff9d685d1b2684baa4408395900a9 100644 (file)
@@ -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.