]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-91880: add try/except around `signal.signal` (#91881)
authorDavid Hewitt <1939362+davidhewitt@users.noreply.github.com>
Mon, 25 Apr 2022 15:56:20 +0000 (16:56 +0100)
committerGitHub <noreply@github.com>
Mon, 25 Apr 2022 15:56:20 +0000 (08:56 -0700)
Fixes gh-91880.

Lib/asyncio/runners.py
Lib/test/test_asyncio/test_runners.py

index 2bb9ca331fd6838b94a2ec95f4461fc1f17caaed..d274576b101340eadaaee317f77dec67bd8c2879 100644 (file)
@@ -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
 
index 42aa07a0e089df22abb0c8c501c048e1eb4ca384..0c2092147842ca1aba56c39da81382dee0b3cfec 100644 (file)
@@ -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__':