Skip to content

Commit

Permalink
GH-99388: add loop_factory parameter to asyncio.run (#99462)
Browse files Browse the repository at this point in the history
  • Loading branch information
kumaraditya303 authored Nov 14, 2022
1 parent f5e326e commit f630027
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 6 deletions.
14 changes: 10 additions & 4 deletions Doc/library/asyncio-runner.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ to simplify async code usage for common wide-spread scenarios.
Running an asyncio Program
==========================

.. function:: run(coro, *, debug=None)
.. function:: run(coro, *, debug=None, loop_factory=None)

Execute the :term:`coroutine` *coro* and return the result.

Expand All @@ -37,9 +37,11 @@ Running an asyncio Program
debug mode explicitly. ``None`` is used to respect the global
:ref:`asyncio-debug-mode` settings.

This function always creates a new event loop and closes it at
the end. It should be used as a main entry point for asyncio
programs, and should ideally only be called once.
If *loop_factory* is not ``None``, it is used to create a new event loop;
otherwise :func:`asyncio.new_event_loop` is used. The loop is closed at the end.
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.

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 All @@ -62,6 +64,10 @@ Running an asyncio Program

*debug* is ``None`` by default to respect the global debug mode settings.

.. versionchanged:: 3.12

Added *loop_factory* parameter.


Runner context manager
======================
Expand Down
5 changes: 5 additions & 0 deletions Doc/whatsnew/3.12.rst
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ asyncio
and will be removed in Python 3.14.
(Contributed by Kumar Aditya in :gh:`94597`.)

* Add *loop_factory* parameter to :func:`asyncio.run` to allow specifying
a custom event loop factory.
(Contributed by Kumar Aditya in :gh:`99388`.)


pathlib
-------

Expand Down
4 changes: 2 additions & 2 deletions Lib/asyncio/runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def _on_sigint(self, signum, frame, main_task):
raise KeyboardInterrupt()


def run(main, *, debug=None):
def run(main, *, debug=None, loop_factory=None):
"""Execute the coroutine and return the result.
This function runs the passed coroutine, taking care of
Expand Down Expand Up @@ -190,7 +190,7 @@ async def main():
raise RuntimeError(
"asyncio.run() cannot be called from a running event loop")

with Runner(debug=debug) as runner:
with Runner(debug=debug, loop_factory=loop_factory) as runner:
return runner.run(main)


Expand Down
10 changes: 10 additions & 0 deletions Lib/test/test_asyncio/test_runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,16 @@ def new_event_loop():
with self.assertRaises(asyncio.CancelledError):
asyncio.run(main())

def test_asyncio_run_loop_factory(self):
factory = mock.Mock()
loop = factory.return_value = self.new_loop()

async def main():
self.assertEqual(asyncio.get_running_loop(), loop)

asyncio.run(main(), loop_factory=factory)
factory.assert_called_once_with()


class RunnerTests(BaseTest):

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add *loop_factory* parameter to :func:`asyncio.run` to allow specifying a custom event loop factory.
Patch by Kumar Aditya.

0 comments on commit f630027

Please sign in to comment.