https://github.com/python/cpython/commit/a391d80f4bf5a3cf5aa95340ca848b9a0294778d
commit: a391d80f4bf5a3cf5aa95340ca848b9a0294778d
branch: main
author: Kumar Aditya <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2024-12-24T17:30:26+05:30
summary:

gh-127949: deprecate asyncio policy classes (#128216)

files:
M Doc/library/asyncio-policy.rst
M Lib/asyncio/__init__.py
M Lib/asyncio/events.py
M Lib/asyncio/unix_events.py
M Lib/asyncio/windows_events.py
M Lib/test/test_asyncio/test_events.py
M Lib/test/test_asyncio/test_runners.py
M Lib/test/test_asyncio/test_windows_events.py

diff --git a/Doc/library/asyncio-policy.rst b/Doc/library/asyncio-policy.rst
index 2d05c3a9f7f157..ea7fe957da7c40 100644
--- a/Doc/library/asyncio-policy.rst
+++ b/Doc/library/asyncio-policy.rst
@@ -87,6 +87,10 @@ The abstract event loop policy base class is defined as 
follows:
 
       This method should never return ``None``.
 
+   .. deprecated:: next
+      The :class:`AbstractEventLoopPolicy` class is deprecated and
+      will be removed in Python 3.16.
+
 
 .. _asyncio-policy-builtin:
 
@@ -109,6 +113,10 @@ asyncio ships with the following built-in policies:
       The :meth:`get_event_loop` method of the default asyncio policy now
       raises a :exc:`RuntimeError` if there is no set event loop.
 
+   .. deprecated:: next
+      The :class:`DefaultEventLoopPolicy` class is deprecated and
+      will be removed in Python 3.16.
+
 
 .. class:: WindowsSelectorEventLoopPolicy
 
@@ -117,6 +125,10 @@ asyncio ships with the following built-in policies:
 
    .. availability:: Windows.
 
+   .. deprecated:: next
+      The :class:`WindowsSelectorEventLoopPolicy` class is deprecated and
+      will be removed in Python 3.16.
+
 
 .. class:: WindowsProactorEventLoopPolicy
 
@@ -125,6 +137,10 @@ asyncio ships with the following built-in policies:
 
    .. availability:: Windows.
 
+   .. deprecated:: next
+      The :class:`WindowsProactorEventLoopPolicy` class is deprecated and
+      will be removed in Python 3.16.
+
 
 .. _asyncio-custom-policies:
 
diff --git a/Lib/asyncio/__init__.py b/Lib/asyncio/__init__.py
index 03165a425eb7d2..edb615b1b6b1c6 100644
--- a/Lib/asyncio/__init__.py
+++ b/Lib/asyncio/__init__.py
@@ -45,3 +45,19 @@
 else:
     from .unix_events import *  # pragma: no cover
     __all__ += unix_events.__all__
+
+def __getattr__(name: str):
+    import warnings
+
+    deprecated = {
+        "AbstractEventLoopPolicy",
+        "DefaultEventLoopPolicy",
+        "WindowsSelectorEventLoopPolicy",
+        "WindowsProactorEventLoopPolicy",
+    }
+    if name in deprecated:
+        warnings._deprecated(f"asyncio.{name}", remove=(3, 16))
+        # deprecated things have underscores in front of them
+        return globals()["_" + name]
+
+    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py
index 1449245edc7c7e..3ade7747149b32 100644
--- a/Lib/asyncio/events.py
+++ b/Lib/asyncio/events.py
@@ -5,7 +5,7 @@
 # SPDX-FileCopyrightText: Copyright (c) 2015-2021 MagicStack Inc.  
http://magic.io
 
 __all__ = (
-    'AbstractEventLoopPolicy',
+    '_AbstractEventLoopPolicy',
     'AbstractEventLoop', 'AbstractServer',
     'Handle', 'TimerHandle',
     '_get_event_loop_policy',
@@ -632,7 +632,7 @@ def set_debug(self, enabled):
         raise NotImplementedError
 
 
-class AbstractEventLoopPolicy:
+class _AbstractEventLoopPolicy:
     """Abstract policy for accessing the event loop."""
 
     def get_event_loop(self):
@@ -655,7 +655,7 @@ def new_event_loop(self):
         the current context, set_event_loop must be called explicitly."""
         raise NotImplementedError
 
-class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy):
+class _BaseDefaultEventLoopPolicy(_AbstractEventLoopPolicy):
     """Default policy implementation for accessing the event loop.
 
     In this policy, each thread has its own event loop.  However, we
@@ -758,8 +758,8 @@ def _init_event_loop_policy():
     global _event_loop_policy
     with _lock:
         if _event_loop_policy is None:  # pragma: no branch
-            from . import DefaultEventLoopPolicy
-            _event_loop_policy = DefaultEventLoopPolicy()
+            from . import _DefaultEventLoopPolicy
+            _event_loop_policy = _DefaultEventLoopPolicy()
 
 
 def _get_event_loop_policy():
@@ -777,7 +777,7 @@ def _set_event_loop_policy(policy):
 
     If policy is None, the default policy is restored."""
     global _event_loop_policy
-    if policy is not None and not isinstance(policy, AbstractEventLoopPolicy):
+    if policy is not None and not isinstance(policy, _AbstractEventLoopPolicy):
         raise TypeError(f"policy must be an instance of 
AbstractEventLoopPolicy or None, not '{type(policy).__name__}'")
     _event_loop_policy = policy
 
@@ -838,7 +838,7 @@ def new_event_loop():
     def on_fork():
         # Reset the loop and wakeupfd in the forked child process.
         if _event_loop_policy is not None:
-            _event_loop_policy._local = BaseDefaultEventLoopPolicy._Local()
+            _event_loop_policy._local = _BaseDefaultEventLoopPolicy._Local()
         _set_running_loop(None)
         signal.set_wakeup_fd(-1)
 
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 0227eb506c6016..f69c6a64c39ae6 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -28,7 +28,7 @@
 
 __all__ = (
     'SelectorEventLoop',
-    'DefaultEventLoopPolicy',
+    '_DefaultEventLoopPolicy',
     'EventLoop',
 )
 
@@ -963,11 +963,11 @@ def can_use_pidfd():
     return True
 
 
-class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
+class _UnixDefaultEventLoopPolicy(events._BaseDefaultEventLoopPolicy):
     """UNIX event loop policy"""
     _loop_factory = _UnixSelectorEventLoop
 
 
 SelectorEventLoop = _UnixSelectorEventLoop
-DefaultEventLoopPolicy = _UnixDefaultEventLoopPolicy
+_DefaultEventLoopPolicy = _UnixDefaultEventLoopPolicy
 EventLoop = SelectorEventLoop
diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py
index bf99bc271c7acd..5f75b17d8ca649 100644
--- a/Lib/asyncio/windows_events.py
+++ b/Lib/asyncio/windows_events.py
@@ -29,8 +29,8 @@
 
 __all__ = (
     'SelectorEventLoop', 'ProactorEventLoop', 'IocpProactor',
-    'DefaultEventLoopPolicy', 'WindowsSelectorEventLoopPolicy',
-    'WindowsProactorEventLoopPolicy', 'EventLoop',
+    '_DefaultEventLoopPolicy', '_WindowsSelectorEventLoopPolicy',
+    '_WindowsProactorEventLoopPolicy', 'EventLoop',
 )
 
 
@@ -891,13 +891,13 @@ def callback(f):
 SelectorEventLoop = _WindowsSelectorEventLoop
 
 
-class WindowsSelectorEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
+class _WindowsSelectorEventLoopPolicy(events._BaseDefaultEventLoopPolicy):
     _loop_factory = SelectorEventLoop
 
 
-class WindowsProactorEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
+class _WindowsProactorEventLoopPolicy(events._BaseDefaultEventLoopPolicy):
     _loop_factory = ProactorEventLoop
 
 
-DefaultEventLoopPolicy = WindowsProactorEventLoopPolicy
+_DefaultEventLoopPolicy = _WindowsProactorEventLoopPolicy
 EventLoop = ProactorEventLoop
diff --git a/Lib/test/test_asyncio/test_events.py 
b/Lib/test/test_asyncio/test_events.py
index d43f66c13d2f96..c626670f72a084 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -2695,14 +2695,26 @@ async def inner():
 
 class PolicyTests(unittest.TestCase):
 
+    def test_abstract_event_loop_policy_deprecation(self):
+        with self.assertWarnsRegex(
+                DeprecationWarning, "'asyncio.AbstractEventLoopPolicy' is 
deprecated"):
+            policy = asyncio.AbstractEventLoopPolicy()
+            self.assertIsInstance(policy, asyncio.AbstractEventLoopPolicy)
+
+    def test_default_event_loop_policy_deprecation(self):
+        with self.assertWarnsRegex(
+                DeprecationWarning, "'asyncio.DefaultEventLoopPolicy' is 
deprecated"):
+            policy = asyncio.DefaultEventLoopPolicy()
+            self.assertIsInstance(policy, asyncio.DefaultEventLoopPolicy)
+
     def test_event_loop_policy(self):
-        policy = asyncio.AbstractEventLoopPolicy()
+        policy = asyncio._AbstractEventLoopPolicy()
         self.assertRaises(NotImplementedError, policy.get_event_loop)
         self.assertRaises(NotImplementedError, policy.set_event_loop, object())
         self.assertRaises(NotImplementedError, policy.new_event_loop)
 
     def test_get_event_loop(self):
-        policy = asyncio.DefaultEventLoopPolicy()
+        policy = asyncio._DefaultEventLoopPolicy()
         self.assertIsNone(policy._local._loop)
 
         with self.assertRaises(RuntimeError):
@@ -2710,7 +2722,7 @@ def test_get_event_loop(self):
         self.assertIsNone(policy._local._loop)
 
     def test_get_event_loop_does_not_call_set_event_loop(self):
-        policy = asyncio.DefaultEventLoopPolicy()
+        policy = asyncio._DefaultEventLoopPolicy()
 
         with mock.patch.object(
                 policy, "set_event_loop",
@@ -2722,7 +2734,7 @@ def 
test_get_event_loop_does_not_call_set_event_loop(self):
             m_set_event_loop.assert_not_called()
 
     def test_get_event_loop_after_set_none(self):
-        policy = asyncio.DefaultEventLoopPolicy()
+        policy = asyncio._DefaultEventLoopPolicy()
         policy.set_event_loop(None)
         self.assertRaises(RuntimeError, policy.get_event_loop)
 
@@ -2730,7 +2742,7 @@ def test_get_event_loop_after_set_none(self):
     def test_get_event_loop_thread(self, m_current_thread):
 
         def f():
-            policy = asyncio.DefaultEventLoopPolicy()
+            policy = asyncio._DefaultEventLoopPolicy()
             self.assertRaises(RuntimeError, policy.get_event_loop)
 
         th = threading.Thread(target=f)
@@ -2738,14 +2750,14 @@ def f():
         th.join()
 
     def test_new_event_loop(self):
-        policy = asyncio.DefaultEventLoopPolicy()
+        policy = asyncio._DefaultEventLoopPolicy()
 
         loop = policy.new_event_loop()
         self.assertIsInstance(loop, asyncio.AbstractEventLoop)
         loop.close()
 
     def test_set_event_loop(self):
-        policy = asyncio.DefaultEventLoopPolicy()
+        policy = asyncio._DefaultEventLoopPolicy()
         old_loop = policy.new_event_loop()
         policy.set_event_loop(old_loop)
 
@@ -2762,7 +2774,7 @@ def test_get_event_loop_policy(self):
         with self.assertWarnsRegex(
                 DeprecationWarning, "'asyncio.get_event_loop_policy' is 
deprecated"):
             policy = asyncio.get_event_loop_policy()
-            self.assertIsInstance(policy, asyncio.AbstractEventLoopPolicy)
+            self.assertIsInstance(policy, asyncio._AbstractEventLoopPolicy)
             self.assertIs(policy, asyncio.get_event_loop_policy())
 
     def test_set_event_loop_policy(self):
@@ -2775,7 +2787,7 @@ def test_set_event_loop_policy(self):
                 DeprecationWarning, "'asyncio.get_event_loop_policy' is 
deprecated"):
             old_policy = asyncio.get_event_loop_policy()
 
-        policy = asyncio.DefaultEventLoopPolicy()
+        policy = asyncio._DefaultEventLoopPolicy()
         with self.assertWarnsRegex(
                 DeprecationWarning, "'asyncio.set_event_loop_policy' is 
deprecated"):
             asyncio.set_event_loop_policy(policy)
@@ -2862,7 +2874,7 @@ def test_get_event_loop_returns_running_loop(self):
         class TestError(Exception):
             pass
 
-        class Policy(asyncio.DefaultEventLoopPolicy):
+        class Policy(asyncio._DefaultEventLoopPolicy):
             def get_event_loop(self):
                 raise TestError
 
@@ -2908,7 +2920,7 @@ async def func():
     def test_get_event_loop_returns_running_loop2(self):
         old_policy = asyncio._get_event_loop_policy()
         try:
-            asyncio._set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
+            asyncio._set_event_loop_policy(asyncio._DefaultEventLoopPolicy())
             loop = asyncio.new_event_loop()
             self.addCleanup(loop.close)
 
diff --git a/Lib/test/test_asyncio/test_runners.py 
b/Lib/test/test_asyncio/test_runners.py
index e1f82f7f7bec0c..21f277bc2d8d5f 100644
--- a/Lib/test/test_asyncio/test_runners.py
+++ b/Lib/test/test_asyncio/test_runners.py
@@ -19,7 +19,7 @@ def interrupt_self():
     _thread.interrupt_main()
 
 
-class TestPolicy(asyncio.AbstractEventLoopPolicy):
+class TestPolicy(asyncio._AbstractEventLoopPolicy):
 
     def __init__(self, loop_factory):
         self.loop_factory = loop_factory
diff --git a/Lib/test/test_asyncio/test_windows_events.py 
b/Lib/test/test_asyncio/test_windows_events.py
index 28b05d24dc25a1..69e9905205eee0 100644
--- a/Lib/test/test_asyncio/test_windows_events.py
+++ b/Lib/test/test_asyncio/test_windows_events.py
@@ -328,14 +328,15 @@ class WinPolicyTests(WindowsEventsTestCase):
 
     def test_selector_win_policy(self):
         async def main():
-            self.assertIsInstance(
-                asyncio.get_running_loop(),
-                asyncio.SelectorEventLoop)
+            self.assertIsInstance(asyncio.get_running_loop(), 
asyncio.SelectorEventLoop)
 
         old_policy = asyncio._get_event_loop_policy()
         try:
-            asyncio._set_event_loop_policy(
-                asyncio.WindowsSelectorEventLoopPolicy())
+            with self.assertWarnsRegex(
+                DeprecationWarning,
+                "'asyncio.WindowsSelectorEventLoopPolicy' is deprecated",
+            ):
+                
asyncio._set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
             asyncio.run(main())
         finally:
             asyncio._set_event_loop_policy(old_policy)
@@ -348,8 +349,11 @@ async def main():
 
         old_policy = asyncio._get_event_loop_policy()
         try:
-            asyncio._set_event_loop_policy(
-                asyncio.WindowsProactorEventLoopPolicy())
+            with self.assertWarnsRegex(
+                DeprecationWarning,
+                "'asyncio.WindowsProactorEventLoopPolicy' is deprecated",
+            ):
+                
asyncio._set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
             asyncio.run(main())
         finally:
             asyncio._set_event_loop_policy(old_policy)

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to