https://github.com/python/cpython/commit/b8c8b8f1d30767e5358ffa93d41e6e27ca60570d
commit: b8c8b8f1d30767e5358ffa93d41e6e27ca60570d
branch: main
author: yihong <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2025-10-09T14:58:01Z
summary:
gh-139391: properly handle `signal.signal()` in `UnixConsole` when called from
a non-main thread (#139392)
files:
A Misc/NEWS.d/next/Library/2025-09-28-16-34-11.gh-issue-139391.nRFnmx.rst
M Lib/_pyrepl/unix_console.py
M Lib/test/test_pyrepl/test_unix_console.py
diff --git a/Lib/_pyrepl/unix_console.py b/Lib/_pyrepl/unix_console.py
index fe45b4eb384067..09247de748ee3b 100644
--- a/Lib/_pyrepl/unix_console.py
+++ b/Lib/_pyrepl/unix_console.py
@@ -390,7 +390,12 @@ def restore(self):
os.write(self.output_fd, b"\033[?7h")
if hasattr(self, "old_sigwinch"):
- signal.signal(signal.SIGWINCH, self.old_sigwinch)
+ try:
+ signal.signal(signal.SIGWINCH, self.old_sigwinch)
+ except ValueError as e:
+ import threading
+ if threading.current_thread() is threading.main_thread():
+ raise e
del self.old_sigwinch
def push_char(self, char: int | bytes) -> None:
diff --git a/Lib/test/test_pyrepl/test_unix_console.py
b/Lib/test/test_pyrepl/test_unix_console.py
index 9ac2e9961df2dc..f4fb9237ffdfd0 100644
--- a/Lib/test/test_pyrepl/test_unix_console.py
+++ b/Lib/test/test_pyrepl/test_unix_console.py
@@ -4,11 +4,12 @@
import signal
import subprocess
import sys
+import threading
import unittest
from functools import partial
from test import support
from test.support import os_helper, force_not_colorized_test_class
-from test.support import script_helper
+from test.support import script_helper, threading_helper
from unittest import TestCase
from unittest.mock import MagicMock, call, patch, ANY, Mock
@@ -318,6 +319,17 @@ def test_restore_with_invalid_environ_on_macos(self,
_os_write):
console.prepare() # needed to call restore()
console.restore() # this should succeed
+ @threading_helper.reap_threads
+ @threading_helper.requires_working_threading()
+ def test_restore_in_thread(self, _os_write):
+ # gh-139391: ensure that console.restore() silently suppresses
+ # exceptions when calling signal.signal() from a non-main thread.
+ console = unix_console([])
+ console.old_sigwinch = signal.SIG_DFL
+ thread = threading.Thread(target=console.restore)
+ thread.start()
+ thread.join() # this should not raise
+
@unittest.skipIf(sys.platform == "win32", "No Unix console on Windows")
class TestUnixConsoleEIOHandling(TestCase):
diff --git
a/Misc/NEWS.d/next/Library/2025-09-28-16-34-11.gh-issue-139391.nRFnmx.rst
b/Misc/NEWS.d/next/Library/2025-09-28-16-34-11.gh-issue-139391.nRFnmx.rst
new file mode 100644
index 00000000000000..93d1ce613bc2d6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-09-28-16-34-11.gh-issue-139391.nRFnmx.rst
@@ -0,0 +1,3 @@
+Fix an issue when, on non-Windows platforms, it was not possible to
+gracefully exit a ``python -m asyncio`` process suspended by Ctrl+Z
+and later resumed by :manpage:`fg` other than with :manpage:`kill`.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]