From 700cf867bcd10de405e6f473acbaeef3ace2d37d Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 15:40:25 -0400 Subject: [PATCH 01/25] Add thread timeout constant --- Lib/asyncio/base_events.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 031071281b38f7..7b9d9eaf87318a 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -66,6 +66,8 @@ # Maximum timeout passed to select to avoid OS limitations MAXIMUM_SELECT_TIMEOUT = 24 * 3600 +# Default timeout for joining each thread in `shutdown_default_executor()` +THREAD_JOIN_TIMEOUT = 300 def _format_handle(handle): cb = handle._callback From 1e7794bec6aeae0da599fcac3bad9a97444c9c2c Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 15:47:37 -0400 Subject: [PATCH 02/25] Add timeout param to `loop.shutdown_default_executor()` --- Lib/asyncio/base_events.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 7b9d9eaf87318a..96654136d5c92c 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -551,7 +551,7 @@ async def shutdown_asyncgens(self): 'asyncgen': agen }) - async def shutdown_default_executor(self): + async def shutdown_default_executor(self, timeout=THREAD_JOIN_TIMEOUT): """Schedule the shutdown of the default executor.""" self._executor_shutdown_called = True if self._default_executor is None: @@ -562,7 +562,7 @@ async def shutdown_default_executor(self): try: await future finally: - thread.join() + thread.join(timeout) def _do_shutdown(self, future): try: From a262c45a6800d3920eb0aaf4f32df62b602ea092 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 19:25:49 -0400 Subject: [PATCH 03/25] Set timeout param default to None --- Lib/asyncio/base_events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 96654136d5c92c..013a825f064ccd 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -551,7 +551,7 @@ async def shutdown_asyncgens(self): 'asyncgen': agen }) - async def shutdown_default_executor(self, timeout=THREAD_JOIN_TIMEOUT): + async def shutdown_default_executor(self, timeout=None): """Schedule the shutdown of the default executor.""" self._executor_shutdown_called = True if self._default_executor is None: From b1bb810425aa5b4994f2e57c2d8d0dd79156c062 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 19:32:34 -0400 Subject: [PATCH 04/25] Update `loop.shutdown_default_executor() docstring --- Lib/asyncio/base_events.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 013a825f064ccd..9034d3a67bd1fd 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -552,7 +552,12 @@ async def shutdown_asyncgens(self): }) async def shutdown_default_executor(self, timeout=None): - """Schedule the shutdown of the default executor.""" + """Schedule the shutdown of the default executor. + + The timeout parameter specifies the amount of time each thread will + be given to finish joining. The default value is None, which means + that each thread will be given an indefinite amount of time to join. + """ self._executor_shutdown_called = True if self._default_executor is None: return From 8a4c30cba94afb345e31c78d2f672e162d109425 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 19:39:58 -0400 Subject: [PATCH 05/25] Move constant to runners.py --- Lib/asyncio/base_events.py | 2 -- Lib/asyncio/runners.py | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 9034d3a67bd1fd..9a984b6a511551 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -66,8 +66,6 @@ # Maximum timeout passed to select to avoid OS limitations MAXIMUM_SELECT_TIMEOUT = 24 * 3600 -# Default timeout for joining each thread in `shutdown_default_executor()` -THREAD_JOIN_TIMEOUT = 300 def _format_handle(handle): cb = handle._callback diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 6c87747e770bb8..8fec803f998b07 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -5,6 +5,10 @@ from . import tasks +# Default timeout for joining each thread in `shutdown_default_executor()` +THREAD_JOIN_TIMEOUT = 300 + + def run(main, *, debug=False): """Run a coroutine. From ebc1b9916935fede428b60920d7787f4e9c5535e Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 20:15:11 -0400 Subject: [PATCH 06/25] Add thread timeout for `asyncio.run()` --- Lib/asyncio/runners.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 8fec803f998b07..9647a496e88c42 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -49,7 +49,8 @@ async def main(): try: _cancel_all_tasks(loop) loop.run_until_complete(loop.shutdown_asyncgens()) - loop.run_until_complete(loop.shutdown_default_executor()) + loop.run_until_complete( + loop.shutdown_default_executor(timeout=THREAD_JOIN_TIMEOUT)) finally: events.set_event_loop(None) loop.close() From 5b90766bbb5e9418dbdc5b0decd4020d8d128334 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 20:17:03 -0400 Subject: [PATCH 07/25] Update `asyncio.run()` docstring for `shutdown_default_executor()` --- Lib/asyncio/runners.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 9647a496e88c42..e64c204f70da52 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -13,8 +13,8 @@ def run(main, *, debug=False): """Run a coroutine. This function runs the passed coroutine, taking care of - managing the asyncio event loop and finalizing asynchronous - generators. + managing the asyncio event loop, finalizing asynchronous + generators, and closing the threadpool. This function cannot be called when another asyncio event loop is running in the same thread. From f189f048c9bb04350a531aaa72105345c631a53c Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 20:19:58 -0400 Subject: [PATCH 08/25] Update `asyncio.run()` docstring for thread timeout --- Lib/asyncio/runners.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index e64c204f70da52..2c0fcb70d0e788 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -25,6 +25,10 @@ def run(main, *, debug=False): It should be used as a main entry point for asyncio programs, and should ideally only be called once. + Each thread within the threadpool is given a timeout duration of 5 + minutes. If the thread hasn't finishing joining within that duration, + the lock is released and the thread is terminated. + Example: async def main(): From 16921a11d75cc91688cdb6a1caf0c520ec41973b Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 20:24:42 -0400 Subject: [PATCH 09/25] Update `asyncio.run()` docs --- Doc/library/asyncio-task.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 1fb88293589518..c91fbeebabc227 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -225,6 +225,10 @@ Running an asyncio Program the end. It should be used as a main entry point for asyncio programs, and should ideally only be called once. + Each thread within the threadpool is given a timeout duration of 5 + minutes. If the thread hasn't finishing joining within that duration, + the lock is released and the thread is terminated. + .. versionadded:: 3.7 .. versionchanged:: 3.9 From b6788188f31215d8d40f3c550fec6679073c8ec5 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 20:25:59 -0400 Subject: [PATCH 10/25] Fix whitespace in `asyncio.run()` docstring --- Lib/asyncio/runners.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 2c0fcb70d0e788..b845fa5bdec53e 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -26,7 +26,7 @@ def run(main, *, debug=False): ideally only be called once. Each thread within the threadpool is given a timeout duration of 5 - minutes. If the thread hasn't finishing joining within that duration, + minutes. If the thread hasn't finishing joining within that duration, the lock is released and the thread is terminated. Example: From e33225751f3bdde1aca706d203afe37ddf9960a4 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 20:31:47 -0400 Subject: [PATCH 11/25] Update `shutdown_default_executor()` docs --- Doc/library/asyncio-eventloop.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 2fd4cf30bd450f..c2b052d842127d 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -167,13 +167,17 @@ Running and stopping the loop .. versionadded:: 3.6 -.. coroutinemethod:: loop.shutdown_default_executor() +.. coroutinemethod:: loop.shutdown_default_executor(timeout=None) Schedule the closure of the default executor and wait for it to join all of the threads in the :class:`ThreadPoolExecutor`. After calling this method, a :exc:`RuntimeError` will be raised if :meth:`loop.run_in_executor` is called while using the default executor. + The *timeout* parameter specifies the amount of time each thread will be + given to finish joining. The default value is ``None``, which means that each + thread will be given an indefinite amount of time to join. + Note that there is no need to call this function when :func:`asyncio.run` is used. From 7f8428b8401127238b5396640adcc6de9d9350ed Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 20:33:39 -0400 Subject: [PATCH 12/25] Patchcheck --- Doc/library/asyncio-eventloop.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index c2b052d842127d..118ff71b2f32cc 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -174,7 +174,7 @@ Running and stopping the loop :exc:`RuntimeError` will be raised if :meth:`loop.run_in_executor` is called while using the default executor. - The *timeout* parameter specifies the amount of time each thread will be + The *timeout* parameter specifies the amount of time each thread will be given to finish joining. The default value is ``None``, which means that each thread will be given an indefinite amount of time to join. From 577b2b26b66a5e27ddc667b236b13d0287123790 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2019 00:37:52 +0000 Subject: [PATCH 13/25] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2019-09-25-00-37-51.bpo-38267.X9Jb5V.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2019-09-25-00-37-51.bpo-38267.X9Jb5V.rst diff --git a/Misc/NEWS.d/next/Library/2019-09-25-00-37-51.bpo-38267.X9Jb5V.rst b/Misc/NEWS.d/next/Library/2019-09-25-00-37-51.bpo-38267.X9Jb5V.rst new file mode 100644 index 00000000000000..b59761cbe8b18f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-09-25-00-37-51.bpo-38267.X9Jb5V.rst @@ -0,0 +1 @@ +Add *timeout* parameter to :meth:`asyncio.loop.shutdown_default_executor()`. \ No newline at end of file From b6730809f578f29b94c687b628874cf32a0ca1ec Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 24 Sep 2019 20:39:21 -0400 Subject: [PATCH 14/25] Fix Misc/NEWS Sphinx role --- .../next/Library/2019-09-25-00-37-51.bpo-38267.X9Jb5V.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2019-09-25-00-37-51.bpo-38267.X9Jb5V.rst b/Misc/NEWS.d/next/Library/2019-09-25-00-37-51.bpo-38267.X9Jb5V.rst index b59761cbe8b18f..79c84ea0ae9f90 100644 --- a/Misc/NEWS.d/next/Library/2019-09-25-00-37-51.bpo-38267.X9Jb5V.rst +++ b/Misc/NEWS.d/next/Library/2019-09-25-00-37-51.bpo-38267.X9Jb5V.rst @@ -1 +1 @@ -Add *timeout* parameter to :meth:`asyncio.loop.shutdown_default_executor()`. \ No newline at end of file +Add *timeout* parameter to :meth:`asyncio.loop.shutdown_default_executor`. From f7c623c3413c49c0ef5fe8631a210c880898e5d5 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Thu, 3 Oct 2019 17:15:57 -0400 Subject: [PATCH 15/25] Fix documentation for timeout parameter --- Doc/library/asyncio-eventloop.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 389dbd53967641..3e53cee78340bc 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -174,8 +174,8 @@ Running and stopping the loop :exc:`RuntimeError` will be raised if :meth:`loop.run_in_executor` is called while using the default executor. - The *timeout* parameter specifies the amount of time each thread will be - given to finish joining. The default value is ``None``, which means that each + The *timeout* parameter specifies the amount of time all of the threads will + be given to finish joining. The default value is ``None``, which means that each thread will be given an indefinite amount of time to join. Note that there is no need to call this function when From 169d2d44beeb44c1b8de68af2fc7cb91f69b05d0 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Thu, 3 Oct 2019 17:18:00 -0400 Subject: [PATCH 16/25] Fix documentation for timeout parameter --- Doc/library/asyncio-eventloop.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index 3e53cee78340bc..e0216b0b418a78 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -175,8 +175,8 @@ Running and stopping the loop while using the default executor. The *timeout* parameter specifies the amount of time all of the threads will - be given to finish joining. The default value is ``None``, which means that each - thread will be given an indefinite amount of time to join. + be given to finish joining. The default value is ``None``, which means the + threads will be given an indefinite amount of time to join. Note that there is no need to call this function when :func:`asyncio.run` is used. From f0dde2db55e8738fac64fc3b82f345d43195e382 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Thu, 3 Oct 2019 18:50:06 -0400 Subject: [PATCH 17/25] Fix asyncio.run() docs Still need to implement "a warning is emitted and the threadpool is closed" --- Doc/library/asyncio-task.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 8bf4aa3fc1ff32..41a0f2af3c6050 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -227,9 +227,9 @@ Running an asyncio Program the end. It should be used as a main entry point for asyncio programs, and should ideally only be called once. - Each thread within the threadpool is given a timeout duration of 5 - minutes. If the thread hasn't finishing joining within that duration, - the lock is released and the thread is terminated. + The threadpool is given a timeout duration of 5 minutes to join its threads. + If the threadpool hasn't finishing joining within that duration, a warning is + emitted and the threadpool is closed. Example:: From b7c0608b7e438fbd83c565eeaa42862c2f7ed34c Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Thu, 3 Oct 2019 18:51:55 -0400 Subject: [PATCH 18/25] Fix loop.shutdown_default_executor() docstring --- Lib/asyncio/base_events.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 9a984b6a511551..651ac232e65a18 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -552,9 +552,9 @@ async def shutdown_asyncgens(self): async def shutdown_default_executor(self, timeout=None): """Schedule the shutdown of the default executor. - The timeout parameter specifies the amount of time each thread will + The timeout parameter specifies the amount of time the threadpool will be given to finish joining. The default value is None, which means - that each thread will be given an indefinite amount of time to join. + that the threadpool will be given an indefinite amount of time. """ self._executor_shutdown_called = True if self._default_executor is None: From 1e95afb7cbde703df63076aa7e70b951d340e17e Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Thu, 3 Oct 2019 19:05:18 -0400 Subject: [PATCH 19/25] Fix loop.shutdown_default_executor docs --- Doc/library/asyncio-eventloop.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index e0216b0b418a78..7633e8a823b3b2 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -174,9 +174,12 @@ Running and stopping the loop :exc:`RuntimeError` will be raised if :meth:`loop.run_in_executor` is called while using the default executor. - The *timeout* parameter specifies the amount of time all of the threads will + The *timeout* parameter specifies the amount of time the threadpool will be given to finish joining. The default value is ``None``, which means the - threads will be given an indefinite amount of time to join. + threadpool will be given an indefinite amount of time. + + If the timeout duration is reached, a warning is emitted and threadpool is + terminated without waiting for its threads to finish joining. Note that there is no need to call this function when :func:`asyncio.run` is used. From 2b1f35dfcfbf2d5d45deb82c2175147193486237 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Thu, 3 Oct 2019 20:48:11 -0400 Subject: [PATCH 20/25] Fix loop.shutdown_default_executor() --- Lib/asyncio/base_events.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 651ac232e65a18..da07f2f84058b2 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -567,6 +567,11 @@ async def shutdown_default_executor(self, timeout=None): finally: thread.join(timeout) + if (thread.is_alive()): + warnings.Warning("The ThreadPoolExecutor did not finishing joining" + f"its threads within {timeout} seconds.") + self._default_executor.shutdown(wait=False) + def _do_shutdown(self, future): try: self._default_executor.shutdown(wait=True) From e5499969f7c876f8e4f6c64946f92d1c4280510b Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Thu, 3 Oct 2019 20:54:31 -0400 Subject: [PATCH 21/25] Fix asyncio.run() docstring --- Lib/asyncio/runners.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 575c9ea2f0f090..9076b895b8d041 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -25,9 +25,8 @@ def run(main, *, debug=False): It should be used as a main entry point for asyncio programs, and should ideally only be called once. - Each thread within the threadpool is given a timeout duration of 5 - minutes. If the thread hasn't finishing joining within that duration, - the lock is released and the thread is terminated. + The threadpool is given a timeout duration of 5 minutes. If its threads + haven't finishing joining within that duration, the threadpool is terminated. Example: From 8a5121c56aeb4aa712df0e3ca80e997241fa35b2 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Thu, 3 Oct 2019 21:02:58 -0400 Subject: [PATCH 22/25] Fix runners.py comment --- Lib/asyncio/runners.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 9076b895b8d041..3ac88777faeee1 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -5,7 +5,7 @@ from . import tasks -# Default timeout for joining each thread in `shutdown_default_executor()` +# Default timeout for joining the threads in the threadpool THREAD_JOIN_TIMEOUT = 300 From 4264c04827d4a4f428561e225094249bf8e089db Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Sat, 5 Oct 2019 15:21:15 -0400 Subject: [PATCH 23/25] Fix warning --- Lib/asyncio/base_events.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index da07f2f84058b2..a2e68408d59eb0 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -568,8 +568,9 @@ async def shutdown_default_executor(self, timeout=None): thread.join(timeout) if (thread.is_alive()): - warnings.Warning("The ThreadPoolExecutor did not finishing joining" - f"its threads within {timeout} seconds.") + warnings.warn("The ThreadPoolExecutor did not finishing joining" + f"its threads within {timeout} seconds.", + RuntimeWarning) self._default_executor.shutdown(wait=False) def _do_shutdown(self, future): From e9a0f19dc39cd9991eca319ad056388fdc68fa97 Mon Sep 17 00:00:00 2001 From: Kyle Stanley Date: Tue, 29 Oct 2019 01:01:56 -0400 Subject: [PATCH 24/25] Fix RuntimeWarning Set the stacklevel to 2 and fix a spacing issue in the message --- Lib/asyncio/base_events.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index a2e68408d59eb0..a58fea468ac9b8 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -568,9 +568,9 @@ async def shutdown_default_executor(self, timeout=None): thread.join(timeout) if (thread.is_alive()): - warnings.warn("The ThreadPoolExecutor did not finishing joining" + warnings.warn("The ThreadPoolExecutor did not finishing joining " f"its threads within {timeout} seconds.", - RuntimeWarning) + RuntimeWarning, stacklevel=2) self._default_executor.shutdown(wait=False) def _do_shutdown(self, future): From d9c2e3722651a46bdafea91302c2774808e6c376 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sun, 25 Sep 2022 11:32:31 -0700 Subject: [PATCH 25/25] Fix style nits --- Doc/library/asyncio-task.rst | 1 - Lib/asyncio/base_events.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 41a0f2af3c6050..0ed68ceccdb370 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -239,7 +239,6 @@ Running an asyncio Program asyncio.run(main()) - .. versionadded:: 3.7 .. versionchanged:: 3.9 diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index a58fea468ac9b8..d93ba634c2bba1 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -567,7 +567,7 @@ async def shutdown_default_executor(self, timeout=None): finally: thread.join(timeout) - if (thread.is_alive()): + if thread.is_alive(): warnings.warn("The ThreadPoolExecutor did not finishing joining " f"its threads within {timeout} seconds.", RuntimeWarning, stacklevel=2)