Skip to content

Commit f630027

Browse files
GH-99388: add loop_factory parameter to asyncio.run (#99462)
1 parent f5e326e commit f630027

File tree

5 files changed

+29
-6
lines changed

5 files changed

+29
-6
lines changed

Doc/library/asyncio-runner.rst

+10-4
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ to simplify async code usage for common wide-spread scenarios.
2222
Running an asyncio Program
2323
==========================
2424

25-
.. function:: run(coro, *, debug=None)
25+
.. function:: run(coro, *, debug=None, loop_factory=None)
2626

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

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

40-
This function always creates a new event loop and closes it at
41-
the end. It should be used as a main entry point for asyncio
42-
programs, and should ideally only be called once.
40+
If *loop_factory* is not ``None``, it is used to create a new event loop;
41+
otherwise :func:`asyncio.new_event_loop` is used. The loop is closed at the end.
42+
This function should be used as a main entry point for asyncio programs,
43+
and should ideally only be called once. It is recommended to use
44+
*loop_factory* to configure the event loop instead of policies.
4345

4446
The executor is given a timeout duration of 5 minutes to shutdown.
4547
If the executor hasn't finished within that duration, a warning is
@@ -62,6 +64,10 @@ Running an asyncio Program
6264

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

67+
.. versionchanged:: 3.12
68+
69+
Added *loop_factory* parameter.
70+
6571

6672
Runner context manager
6773
======================

Doc/whatsnew/3.12.rst

+5
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@ asyncio
217217
and will be removed in Python 3.14.
218218
(Contributed by Kumar Aditya in :gh:`94597`.)
219219

220+
* Add *loop_factory* parameter to :func:`asyncio.run` to allow specifying
221+
a custom event loop factory.
222+
(Contributed by Kumar Aditya in :gh:`99388`.)
223+
224+
220225
pathlib
221226
-------
222227

Lib/asyncio/runners.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def _on_sigint(self, signum, frame, main_task):
157157
raise KeyboardInterrupt()
158158

159159

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

193-
with Runner(debug=debug) as runner:
193+
with Runner(debug=debug, loop_factory=loop_factory) as runner:
194194
return runner.run(main)
195195

196196

Lib/test/test_asyncio/test_runners.py

+10
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,16 @@ def new_event_loop():
257257
with self.assertRaises(asyncio.CancelledError):
258258
asyncio.run(main())
259259

260+
def test_asyncio_run_loop_factory(self):
261+
factory = mock.Mock()
262+
loop = factory.return_value = self.new_loop()
263+
264+
async def main():
265+
self.assertEqual(asyncio.get_running_loop(), loop)
266+
267+
asyncio.run(main(), loop_factory=factory)
268+
factory.assert_called_once_with()
269+
260270

261271
class RunnerTests(BaseTest):
262272

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

0 commit comments

Comments
 (0)