[Python-checkins] gh-91880: add try/except around `signal.signal` (#91881)

gvanrossum webhook-mailer at python.org
Mon Apr 25 11:56:31 EDT 2022


https://github.com/python/cpython/commit/1cd8c29dace2dc6b91503803113fea4288ca842b
commit: 1cd8c29dace2dc6b91503803113fea4288ca842b
branch: main
author: David Hewitt <1939362+davidhewitt at users.noreply.github.com>
committer: gvanrossum <gvanrossum at gmail.com>
date: 2022-04-25T08:56:20-07:00
summary:

gh-91880: add try/except around `signal.signal` (#91881)

Fixes gh-91880.

files:
M Lib/asyncio/runners.py
M Lib/test/test_asyncio/test_runners.py

diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py
index 2bb9ca331fd68..d274576b10134 100644
--- a/Lib/asyncio/runners.py
+++ b/Lib/asyncio/runners.py
@@ -100,7 +100,13 @@ def run(self, coro, *, context=None):
             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 42aa07a0e089d..0c2092147842c 100644
--- a/Lib/test/test_asyncio/test_runners.py
+++ b/Lib/test/test_asyncio/test_runners.py
@@ -3,10 +3,12 @@
 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 @@ async def coro():
         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__':



More information about the Python-checkins mailing list