Skip to content

Commit

Permalink
pythongh-94597: Add asyncio.EventLoop (python#110723)
Browse files Browse the repository at this point in the history
This is needed to pave the way for deprecating and eventually killing the event loop policy system (which is over-engineered and rarely used).
  • Loading branch information
graingert authored and Glyphack committed Jan 27, 2024
1 parent 3799ce9 commit 356e4bb
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 5 deletions.
16 changes: 12 additions & 4 deletions Doc/library/asyncio-eventloop.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1686,13 +1686,13 @@ Event Loop Implementations
asyncio ships with two different event loop implementations:
:class:`SelectorEventLoop` and :class:`ProactorEventLoop`.

By default asyncio is configured to use :class:`SelectorEventLoop`
on Unix and :class:`ProactorEventLoop` on Windows.
By default asyncio is configured to use :class:`EventLoop`.


.. class:: SelectorEventLoop

An event loop based on the :mod:`selectors` module.
A subclass of :class:`AbstractEventLoop` based on the
:mod:`selectors` module.

Uses the most efficient *selector* available for the given
platform. It is also possible to manually configure the
Expand All @@ -1714,7 +1714,7 @@ on Unix and :class:`ProactorEventLoop` on Windows.

.. class:: ProactorEventLoop

An event loop for Windows that uses "I/O Completion Ports" (IOCP).
A subclass of :class:`AbstractEventLoop` for Windows that uses "I/O Completion Ports" (IOCP).

.. availability:: Windows.

Expand All @@ -1723,6 +1723,14 @@ on Unix and :class:`ProactorEventLoop` on Windows.
`MSDN documentation on I/O Completion Ports
<https://docs.microsoft.com/en-ca/windows/desktop/FileIO/i-o-completion-ports>`_.

.. class:: EventLoop

An alias to the most efficient available subclass of :class:`AbstractEventLoop` for the given
platform.

It is an alias to :class:`SelectorEventLoop` on Unix and :class:`ProactorEventLoop` on Windows.

.. versionadded:: 3.13

.. class:: AbstractEventLoop

Expand Down
2 changes: 2 additions & 0 deletions Doc/library/asyncio-runner.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ Running an asyncio Program
This function should be used as a main entry point for asyncio programs,
and should ideally only be called once. It is recommended to use
*loop_factory* to configure the event loop instead of policies.
Passing :class:`asyncio.EventLoop` allows running asyncio without the
policy system.

The executor is given a timeout duration of 5 minutes to shutdown.
If the executor hasn't finished within that duration, a warning is
Expand Down
2 changes: 2 additions & 0 deletions Lib/asyncio/unix_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
'FastChildWatcher', 'PidfdChildWatcher',
'MultiLoopChildWatcher', 'ThreadedChildWatcher',
'DefaultEventLoopPolicy',
'EventLoop',
)


Expand Down Expand Up @@ -1510,3 +1511,4 @@ def set_child_watcher(self, watcher):

SelectorEventLoop = _UnixSelectorEventLoop
DefaultEventLoopPolicy = _UnixDefaultEventLoopPolicy
EventLoop = SelectorEventLoop
3 changes: 2 additions & 1 deletion Lib/asyncio/windows_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
__all__ = (
'SelectorEventLoop', 'ProactorEventLoop', 'IocpProactor',
'DefaultEventLoopPolicy', 'WindowsSelectorEventLoopPolicy',
'WindowsProactorEventLoopPolicy',
'WindowsProactorEventLoopPolicy', 'EventLoop',
)


Expand Down Expand Up @@ -894,3 +894,4 @@ class WindowsProactorEventLoopPolicy(events.BaseDefaultEventLoopPolicy):


DefaultEventLoopPolicy = WindowsProactorEventLoopPolicy
EventLoop = ProactorEventLoop
11 changes: 11 additions & 0 deletions Lib/test/test_asyncio/test_runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import contextvars
import re
import signal
import sys
import threading
import unittest
from test.test_asyncio import utils as test_utils
Expand Down Expand Up @@ -272,6 +273,16 @@ async def main():
asyncio.run(main(), loop_factory=factory)
factory.assert_called_once_with()

def test_loop_factory_default_event_loop(self):
async def main():
if sys.platform == "win32":
self.assertIsInstance(asyncio.get_running_loop(), asyncio.ProactorEventLoop)
else:
self.assertIsInstance(asyncio.get_running_loop(), asyncio.SelectorEventLoop)


asyncio.run(main(), loop_factory=asyncio.EventLoop)


class RunnerTests(BaseTest):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added :class:`asyncio.EventLoop` for use with the :func:`asyncio.run` *loop_factory* kwarg to avoid calling the asyncio policy system.

0 comments on commit 356e4bb

Please sign in to comment.