mirror of https://github.com/python/cpython.git
gh-127949: deprecate asyncio policy classes (#128216)
This commit is contained in:
parent
3f6a618e49
commit
a391d80f4b
|
@ -87,6 +87,10 @@ The abstract event loop policy base class is defined as follows:
|
||||||
|
|
||||||
This method should never return ``None``.
|
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:
|
.. _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
|
The :meth:`get_event_loop` method of the default asyncio policy now
|
||||||
raises a :exc:`RuntimeError` if there is no set event loop.
|
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
|
.. class:: WindowsSelectorEventLoopPolicy
|
||||||
|
|
||||||
|
@ -117,6 +125,10 @@ asyncio ships with the following built-in policies:
|
||||||
|
|
||||||
.. availability:: Windows.
|
.. availability:: Windows.
|
||||||
|
|
||||||
|
.. deprecated:: next
|
||||||
|
The :class:`WindowsSelectorEventLoopPolicy` class is deprecated and
|
||||||
|
will be removed in Python 3.16.
|
||||||
|
|
||||||
|
|
||||||
.. class:: WindowsProactorEventLoopPolicy
|
.. class:: WindowsProactorEventLoopPolicy
|
||||||
|
|
||||||
|
@ -125,6 +137,10 @@ asyncio ships with the following built-in policies:
|
||||||
|
|
||||||
.. availability:: Windows.
|
.. availability:: Windows.
|
||||||
|
|
||||||
|
.. deprecated:: next
|
||||||
|
The :class:`WindowsProactorEventLoopPolicy` class is deprecated and
|
||||||
|
will be removed in Python 3.16.
|
||||||
|
|
||||||
|
|
||||||
.. _asyncio-custom-policies:
|
.. _asyncio-custom-policies:
|
||||||
|
|
||||||
|
|
|
@ -45,3 +45,19 @@
|
||||||
else:
|
else:
|
||||||
from .unix_events import * # pragma: no cover
|
from .unix_events import * # pragma: no cover
|
||||||
__all__ += unix_events.__all__
|
__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}")
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
# SPDX-FileCopyrightText: Copyright (c) 2015-2021 MagicStack Inc. http://magic.io
|
# SPDX-FileCopyrightText: Copyright (c) 2015-2021 MagicStack Inc. http://magic.io
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AbstractEventLoopPolicy',
|
'_AbstractEventLoopPolicy',
|
||||||
'AbstractEventLoop', 'AbstractServer',
|
'AbstractEventLoop', 'AbstractServer',
|
||||||
'Handle', 'TimerHandle',
|
'Handle', 'TimerHandle',
|
||||||
'_get_event_loop_policy',
|
'_get_event_loop_policy',
|
||||||
|
@ -632,7 +632,7 @@ def set_debug(self, enabled):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class AbstractEventLoopPolicy:
|
class _AbstractEventLoopPolicy:
|
||||||
"""Abstract policy for accessing the event loop."""
|
"""Abstract policy for accessing the event loop."""
|
||||||
|
|
||||||
def get_event_loop(self):
|
def get_event_loop(self):
|
||||||
|
@ -655,7 +655,7 @@ def new_event_loop(self):
|
||||||
the current context, set_event_loop must be called explicitly."""
|
the current context, set_event_loop must be called explicitly."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy):
|
class _BaseDefaultEventLoopPolicy(_AbstractEventLoopPolicy):
|
||||||
"""Default policy implementation for accessing the event loop.
|
"""Default policy implementation for accessing the event loop.
|
||||||
|
|
||||||
In this policy, each thread has its own event loop. However, we
|
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
|
global _event_loop_policy
|
||||||
with _lock:
|
with _lock:
|
||||||
if _event_loop_policy is None: # pragma: no branch
|
if _event_loop_policy is None: # pragma: no branch
|
||||||
from . import DefaultEventLoopPolicy
|
from . import _DefaultEventLoopPolicy
|
||||||
_event_loop_policy = DefaultEventLoopPolicy()
|
_event_loop_policy = _DefaultEventLoopPolicy()
|
||||||
|
|
||||||
|
|
||||||
def _get_event_loop_policy():
|
def _get_event_loop_policy():
|
||||||
|
@ -777,7 +777,7 @@ def _set_event_loop_policy(policy):
|
||||||
|
|
||||||
If policy is None, the default policy is restored."""
|
If policy is None, the default policy is restored."""
|
||||||
global _event_loop_policy
|
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__}'")
|
raise TypeError(f"policy must be an instance of AbstractEventLoopPolicy or None, not '{type(policy).__name__}'")
|
||||||
_event_loop_policy = policy
|
_event_loop_policy = policy
|
||||||
|
|
||||||
|
@ -838,7 +838,7 @@ def new_event_loop():
|
||||||
def on_fork():
|
def on_fork():
|
||||||
# Reset the loop and wakeupfd in the forked child process.
|
# Reset the loop and wakeupfd in the forked child process.
|
||||||
if _event_loop_policy is not None:
|
if _event_loop_policy is not None:
|
||||||
_event_loop_policy._local = BaseDefaultEventLoopPolicy._Local()
|
_event_loop_policy._local = _BaseDefaultEventLoopPolicy._Local()
|
||||||
_set_running_loop(None)
|
_set_running_loop(None)
|
||||||
signal.set_wakeup_fd(-1)
|
signal.set_wakeup_fd(-1)
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'SelectorEventLoop',
|
'SelectorEventLoop',
|
||||||
'DefaultEventLoopPolicy',
|
'_DefaultEventLoopPolicy',
|
||||||
'EventLoop',
|
'EventLoop',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -963,11 +963,11 @@ def can_use_pidfd():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
|
class _UnixDefaultEventLoopPolicy(events._BaseDefaultEventLoopPolicy):
|
||||||
"""UNIX event loop policy"""
|
"""UNIX event loop policy"""
|
||||||
_loop_factory = _UnixSelectorEventLoop
|
_loop_factory = _UnixSelectorEventLoop
|
||||||
|
|
||||||
|
|
||||||
SelectorEventLoop = _UnixSelectorEventLoop
|
SelectorEventLoop = _UnixSelectorEventLoop
|
||||||
DefaultEventLoopPolicy = _UnixDefaultEventLoopPolicy
|
_DefaultEventLoopPolicy = _UnixDefaultEventLoopPolicy
|
||||||
EventLoop = SelectorEventLoop
|
EventLoop = SelectorEventLoop
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'SelectorEventLoop', 'ProactorEventLoop', 'IocpProactor',
|
'SelectorEventLoop', 'ProactorEventLoop', 'IocpProactor',
|
||||||
'DefaultEventLoopPolicy', 'WindowsSelectorEventLoopPolicy',
|
'_DefaultEventLoopPolicy', '_WindowsSelectorEventLoopPolicy',
|
||||||
'WindowsProactorEventLoopPolicy', 'EventLoop',
|
'_WindowsProactorEventLoopPolicy', 'EventLoop',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -891,13 +891,13 @@ def callback(f):
|
||||||
SelectorEventLoop = _WindowsSelectorEventLoop
|
SelectorEventLoop = _WindowsSelectorEventLoop
|
||||||
|
|
||||||
|
|
||||||
class WindowsSelectorEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
|
class _WindowsSelectorEventLoopPolicy(events._BaseDefaultEventLoopPolicy):
|
||||||
_loop_factory = SelectorEventLoop
|
_loop_factory = SelectorEventLoop
|
||||||
|
|
||||||
|
|
||||||
class WindowsProactorEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
|
class _WindowsProactorEventLoopPolicy(events._BaseDefaultEventLoopPolicy):
|
||||||
_loop_factory = ProactorEventLoop
|
_loop_factory = ProactorEventLoop
|
||||||
|
|
||||||
|
|
||||||
DefaultEventLoopPolicy = WindowsProactorEventLoopPolicy
|
_DefaultEventLoopPolicy = _WindowsProactorEventLoopPolicy
|
||||||
EventLoop = ProactorEventLoop
|
EventLoop = ProactorEventLoop
|
||||||
|
|
|
@ -2695,14 +2695,26 @@ async def inner():
|
||||||
|
|
||||||
class PolicyTests(unittest.TestCase):
|
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):
|
def test_event_loop_policy(self):
|
||||||
policy = asyncio.AbstractEventLoopPolicy()
|
policy = asyncio._AbstractEventLoopPolicy()
|
||||||
self.assertRaises(NotImplementedError, policy.get_event_loop)
|
self.assertRaises(NotImplementedError, policy.get_event_loop)
|
||||||
self.assertRaises(NotImplementedError, policy.set_event_loop, object())
|
self.assertRaises(NotImplementedError, policy.set_event_loop, object())
|
||||||
self.assertRaises(NotImplementedError, policy.new_event_loop)
|
self.assertRaises(NotImplementedError, policy.new_event_loop)
|
||||||
|
|
||||||
def test_get_event_loop(self):
|
def test_get_event_loop(self):
|
||||||
policy = asyncio.DefaultEventLoopPolicy()
|
policy = asyncio._DefaultEventLoopPolicy()
|
||||||
self.assertIsNone(policy._local._loop)
|
self.assertIsNone(policy._local._loop)
|
||||||
|
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
|
@ -2710,7 +2722,7 @@ def test_get_event_loop(self):
|
||||||
self.assertIsNone(policy._local._loop)
|
self.assertIsNone(policy._local._loop)
|
||||||
|
|
||||||
def test_get_event_loop_does_not_call_set_event_loop(self):
|
def test_get_event_loop_does_not_call_set_event_loop(self):
|
||||||
policy = asyncio.DefaultEventLoopPolicy()
|
policy = asyncio._DefaultEventLoopPolicy()
|
||||||
|
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
policy, "set_event_loop",
|
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()
|
m_set_event_loop.assert_not_called()
|
||||||
|
|
||||||
def test_get_event_loop_after_set_none(self):
|
def test_get_event_loop_after_set_none(self):
|
||||||
policy = asyncio.DefaultEventLoopPolicy()
|
policy = asyncio._DefaultEventLoopPolicy()
|
||||||
policy.set_event_loop(None)
|
policy.set_event_loop(None)
|
||||||
self.assertRaises(RuntimeError, policy.get_event_loop)
|
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 test_get_event_loop_thread(self, m_current_thread):
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
policy = asyncio.DefaultEventLoopPolicy()
|
policy = asyncio._DefaultEventLoopPolicy()
|
||||||
self.assertRaises(RuntimeError, policy.get_event_loop)
|
self.assertRaises(RuntimeError, policy.get_event_loop)
|
||||||
|
|
||||||
th = threading.Thread(target=f)
|
th = threading.Thread(target=f)
|
||||||
|
@ -2738,14 +2750,14 @@ def f():
|
||||||
th.join()
|
th.join()
|
||||||
|
|
||||||
def test_new_event_loop(self):
|
def test_new_event_loop(self):
|
||||||
policy = asyncio.DefaultEventLoopPolicy()
|
policy = asyncio._DefaultEventLoopPolicy()
|
||||||
|
|
||||||
loop = policy.new_event_loop()
|
loop = policy.new_event_loop()
|
||||||
self.assertIsInstance(loop, asyncio.AbstractEventLoop)
|
self.assertIsInstance(loop, asyncio.AbstractEventLoop)
|
||||||
loop.close()
|
loop.close()
|
||||||
|
|
||||||
def test_set_event_loop(self):
|
def test_set_event_loop(self):
|
||||||
policy = asyncio.DefaultEventLoopPolicy()
|
policy = asyncio._DefaultEventLoopPolicy()
|
||||||
old_loop = policy.new_event_loop()
|
old_loop = policy.new_event_loop()
|
||||||
policy.set_event_loop(old_loop)
|
policy.set_event_loop(old_loop)
|
||||||
|
|
||||||
|
@ -2762,7 +2774,7 @@ def test_get_event_loop_policy(self):
|
||||||
with self.assertWarnsRegex(
|
with self.assertWarnsRegex(
|
||||||
DeprecationWarning, "'asyncio.get_event_loop_policy' is deprecated"):
|
DeprecationWarning, "'asyncio.get_event_loop_policy' is deprecated"):
|
||||||
policy = asyncio.get_event_loop_policy()
|
policy = asyncio.get_event_loop_policy()
|
||||||
self.assertIsInstance(policy, asyncio.AbstractEventLoopPolicy)
|
self.assertIsInstance(policy, asyncio._AbstractEventLoopPolicy)
|
||||||
self.assertIs(policy, asyncio.get_event_loop_policy())
|
self.assertIs(policy, asyncio.get_event_loop_policy())
|
||||||
|
|
||||||
def test_set_event_loop_policy(self):
|
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"):
|
DeprecationWarning, "'asyncio.get_event_loop_policy' is deprecated"):
|
||||||
old_policy = asyncio.get_event_loop_policy()
|
old_policy = asyncio.get_event_loop_policy()
|
||||||
|
|
||||||
policy = asyncio.DefaultEventLoopPolicy()
|
policy = asyncio._DefaultEventLoopPolicy()
|
||||||
with self.assertWarnsRegex(
|
with self.assertWarnsRegex(
|
||||||
DeprecationWarning, "'asyncio.set_event_loop_policy' is deprecated"):
|
DeprecationWarning, "'asyncio.set_event_loop_policy' is deprecated"):
|
||||||
asyncio.set_event_loop_policy(policy)
|
asyncio.set_event_loop_policy(policy)
|
||||||
|
@ -2862,7 +2874,7 @@ def test_get_event_loop_returns_running_loop(self):
|
||||||
class TestError(Exception):
|
class TestError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Policy(asyncio.DefaultEventLoopPolicy):
|
class Policy(asyncio._DefaultEventLoopPolicy):
|
||||||
def get_event_loop(self):
|
def get_event_loop(self):
|
||||||
raise TestError
|
raise TestError
|
||||||
|
|
||||||
|
@ -2908,7 +2920,7 @@ async def func():
|
||||||
def test_get_event_loop_returns_running_loop2(self):
|
def test_get_event_loop_returns_running_loop2(self):
|
||||||
old_policy = asyncio._get_event_loop_policy()
|
old_policy = asyncio._get_event_loop_policy()
|
||||||
try:
|
try:
|
||||||
asyncio._set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
|
asyncio._set_event_loop_policy(asyncio._DefaultEventLoopPolicy())
|
||||||
loop = asyncio.new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
self.addCleanup(loop.close)
|
self.addCleanup(loop.close)
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ def interrupt_self():
|
||||||
_thread.interrupt_main()
|
_thread.interrupt_main()
|
||||||
|
|
||||||
|
|
||||||
class TestPolicy(asyncio.AbstractEventLoopPolicy):
|
class TestPolicy(asyncio._AbstractEventLoopPolicy):
|
||||||
|
|
||||||
def __init__(self, loop_factory):
|
def __init__(self, loop_factory):
|
||||||
self.loop_factory = loop_factory
|
self.loop_factory = loop_factory
|
||||||
|
|
|
@ -328,14 +328,15 @@ class WinPolicyTests(WindowsEventsTestCase):
|
||||||
|
|
||||||
def test_selector_win_policy(self):
|
def test_selector_win_policy(self):
|
||||||
async def main():
|
async def main():
|
||||||
self.assertIsInstance(
|
self.assertIsInstance(asyncio.get_running_loop(), asyncio.SelectorEventLoop)
|
||||||
asyncio.get_running_loop(),
|
|
||||||
asyncio.SelectorEventLoop)
|
|
||||||
|
|
||||||
old_policy = asyncio._get_event_loop_policy()
|
old_policy = asyncio._get_event_loop_policy()
|
||||||
try:
|
try:
|
||||||
asyncio._set_event_loop_policy(
|
with self.assertWarnsRegex(
|
||||||
asyncio.WindowsSelectorEventLoopPolicy())
|
DeprecationWarning,
|
||||||
|
"'asyncio.WindowsSelectorEventLoopPolicy' is deprecated",
|
||||||
|
):
|
||||||
|
asyncio._set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||||
asyncio.run(main())
|
asyncio.run(main())
|
||||||
finally:
|
finally:
|
||||||
asyncio._set_event_loop_policy(old_policy)
|
asyncio._set_event_loop_policy(old_policy)
|
||||||
|
@ -348,8 +349,11 @@ async def main():
|
||||||
|
|
||||||
old_policy = asyncio._get_event_loop_policy()
|
old_policy = asyncio._get_event_loop_policy()
|
||||||
try:
|
try:
|
||||||
asyncio._set_event_loop_policy(
|
with self.assertWarnsRegex(
|
||||||
asyncio.WindowsProactorEventLoopPolicy())
|
DeprecationWarning,
|
||||||
|
"'asyncio.WindowsProactorEventLoopPolicy' is deprecated",
|
||||||
|
):
|
||||||
|
asyncio._set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
|
||||||
asyncio.run(main())
|
asyncio.run(main())
|
||||||
finally:
|
finally:
|
||||||
asyncio._set_event_loop_policy(old_policy)
|
asyncio._set_event_loop_policy(old_policy)
|
||||||
|
|
Loading…
Reference in New Issue