]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
asyncio: Deprecate AnyThreadEventLoopPolicy
authorBen Darnell <ben@bendarnell.com>
Fri, 3 Dec 2021 18:07:30 +0000 (13:07 -0500)
committerBen Darnell <ben@bendarnell.com>
Sun, 16 Jan 2022 21:49:19 +0000 (16:49 -0500)
Implicit creation of event loops has been deprecated in Python 3.10.
Since AnyThreadEventLoopPolicy modifies the rules for implicit loop
creation, it is also deprecated.

tornado/platform/asyncio.py
tornado/test/asyncio_test.py

index 5e9c776d02ef00b8e9de8d901438e38a00a89716..de8f057f5d5bef85f9aae21a490eb763bdddb375 100644 (file)
@@ -32,6 +32,7 @@ import socket
 import sys
 import threading
 import typing
+import warnings
 from tornado.gen import convert_yielded
 from tornado.ioloop import IOLoop, _Selectable
 
@@ -391,8 +392,25 @@ class AnyThreadEventLoopPolicy(_BasePolicy):  # type: ignore
 
     .. versionadded:: 5.0
 
+    .. deprecated:: 6.2
+
+        ``AnyThreadEventLoopPolicy`` affects the implicit creation
+        of an event loop, which is deprecated in Python 3.10 and
+        will be removed in a future version of Python. At that time
+        ``AnyThreadEventLoopPolicy`` will no longer be useful.
+        If you are relying on it, use `asyncio.new_event_loop`
+        or `asyncio.run` explicitly in any non-main threads that
+        need event loops.
     """
 
+    def __init__(self) -> None:
+        super().__init__()
+        warnings.warn(
+            "AnyThreadEventLoopPolicy is deprecated, use asyncio.run "
+            "or asyncio.new_event_loop instead",
+            DeprecationWarning,
+        )
+
     def get_event_loop(self) -> asyncio.AbstractEventLoop:
         try:
             return super().get_event_loop()
index 3f9f3389a2e3b5a27ac701ace6eaf9be87f38505..72a085390d36be60a0bd2e457fd97a9e79565735 100644 (file)
@@ -12,6 +12,7 @@
 
 import asyncio
 import unittest
+import warnings
 
 from concurrent.futures import ThreadPoolExecutor
 from tornado import gen
@@ -171,17 +172,21 @@ class AnyThreadEventLoopPolicyTest(unittest.TestCase):
         return future.result()
 
     def run_policy_test(self, accessor, expected_type):
-        # With the default policy, non-main threads don't get an event
-        # loop.
-        self.assertRaises(
-            (RuntimeError, AssertionError), 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()  # type: ignore
+        with warnings.catch_warnings():
+            warnings.simplefilter("ignore", DeprecationWarning)
+            # With the default policy, non-main threads don't get an event
+            # loop.
+            self.assertRaises(
+                (RuntimeError, AssertionError), 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()  # type: ignore
 
     def test_asyncio_accessor(self):
         self.run_policy_test(asyncio.get_event_loop, asyncio.AbstractEventLoop)