From 318d0d79738a8e084a9136ad3b5d5b3791e0f5bc Mon Sep 17 00:00:00 2001 From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Date: Mon, 14 Nov 2022 08:18:20 +0000 Subject: [PATCH 1/3] add *loop_factory* parameter --- Doc/library/asyncio-runner.rst | 14 ++++++++++---- Doc/whatsnew/3.12.rst | 5 +++++ Lib/asyncio/runners.py | 4 ++-- Lib/test/test_asyncio/test_runners.py | 10 ++++++++++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst index c43d664eba717f..b0cf9487d0f414 100644 --- a/Doc/library/asyncio-runner.rst +++ b/Doc/library/asyncio-runner.rst @@ -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. @@ -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 and the loop is closed at the end. + It 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 @@ -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 ====================== diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 37b9fb1ea4e89e..a2f79c0e3d38a7 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -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 ------- diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index b1c4dbd7619721..1b89236599aad7 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -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 @@ -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) diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 1308b7e2ba4f82..811cf8b72488b8 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -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): From 6eef5bf03464119908ed644019acdd7a37ea0531 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 08:21:58 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2022-11-14-08-21-56.gh-issue-99388.UWSlwp.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-11-14-08-21-56.gh-issue-99388.UWSlwp.rst diff --git a/Misc/NEWS.d/next/Library/2022-11-14-08-21-56.gh-issue-99388.UWSlwp.rst b/Misc/NEWS.d/next/Library/2022-11-14-08-21-56.gh-issue-99388.UWSlwp.rst new file mode 100644 index 00000000000000..f35799d454573e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-11-14-08-21-56.gh-issue-99388.UWSlwp.rst @@ -0,0 +1,2 @@ +Add *loop_factory* parameter to :func:`asyncio.run` to allow specifying a custom event loop factory. +Patch by Kumar Aditya. From d2f154656b5238db026c6e7a46657a0740bc2a3e Mon Sep 17 00:00:00 2001 From: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> Date: Mon, 14 Nov 2022 22:28:02 +0530 Subject: [PATCH 3/3] Update Doc/library/asyncio-runner.rst Co-authored-by: Guido van Rossum --- Doc/library/asyncio-runner.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst index b0cf9487d0f414..b68b2570ef071e 100644 --- a/Doc/library/asyncio-runner.rst +++ b/Doc/library/asyncio-runner.rst @@ -37,11 +37,11 @@ Running an asyncio Program debug mode explicitly. ``None`` is used to respect the global :ref:`asyncio-debug-mode` settings. - If *loop_factory* is not ``None``, it is used to create a new event loop - otherwise :func:`asyncio.new_event_loop` is used and the loop is closed at the end. - It 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. + 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