From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Mon, 25 Apr 2022 15:56:20 +0000 (+0100) Subject: gh-91880: add try/except around `signal.signal` (#91881) X-Git-Tag: v3.11.0b1~222 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1cd8c29dace2dc6b91503803113fea4288ca842b;p=thirdparty%2FPython%2Fcpython.git gh-91880: add try/except around `signal.signal` (#91881) Fixes gh-91880. --- diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index 2bb9ca331fd6..d274576b1013 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -100,7 +100,13 @@ class Runner: and signal.getsignal(signal.SIGINT) is signal.default_int_handler ): sigint_handler = functools.partial(self._on_sigint, main_task=task) - signal.signal(signal.SIGINT, sigint_handler) + try: + signal.signal(signal.SIGINT, sigint_handler) + except ValueError: + # `signal.signal` may throw if `threading.main_thread` does + # not support signals (e.g. embedded interpreter with signals + # not registered - see gh-91880) + signal_handler = None else: sigint_handler = None diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 42aa07a0e089..0c2092147842 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -3,10 +3,12 @@ import asyncio import contextvars import gc import re +import signal import threading import unittest from unittest import mock +from unittest.mock import patch from test.test_asyncio import utils as test_utils @@ -374,6 +376,23 @@ class RunnerTests(BaseTest): with asyncio.Runner() as runner: with self.assertRaises(asyncio.CancelledError): runner.run(coro()) + + def test_signal_install_not_supported_ok(self): + # signal.signal() can throw if the "main thread" doensn't have signals enabled + assert threading.current_thread() is threading.main_thread() + + async def coro(): + pass + + with asyncio.Runner() as runner: + with patch.object( + signal, + "signal", + side_effect=ValueError( + "signal only works in main thread of the main interpreter" + ) + ): + runner.run(coro()) if __name__ == '__main__':