Skip to content

Commit c0bb775

Browse files
committed
fix: close issue 139391 by ignore the error...
Signed-off-by: yihong0618 <[email protected]>
1 parent 89b5571 commit c0bb775

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

Lib/_pyrepl/unix_console.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,15 @@ def restore(self):
390390
os.write(self.output_fd, b"\033[?7h")
391391

392392
if hasattr(self, "old_sigwinch"):
393-
signal.signal(signal.SIGWINCH, self.old_sigwinch)
393+
# Only restore signal handler if we're in the main thread
394+
# signal.signal() only works in the main thread of the main interpreter
395+
try:
396+
signal.signal(signal.SIGWINCH, self.old_sigwinch)
397+
except ValueError:
398+
# This can happen when called from a non-main thread
399+
# (e.g., asyncio REPL). In this case, we skip signal restoration
400+
# to avoid the "signal only works in main thread" error.
401+
pass
394402
del self.old_sigwinch
395403

396404
def push_char(self, char: int | bytes) -> None:

Lib/test/test_pyrepl/test_unix_console.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,24 @@ def test_restore_with_invalid_environ_on_macos(self, _os_write):
317317
console.prepare() # needed to call restore()
318318
console.restore() # this should succeed
319319

320+
def test_restore_in_thread(self, _os_write):
321+
# for gh-139391
322+
import threading
323+
console = unix_console([])
324+
console.old_sigwinch = signal.SIG_DFL
325+
exception_caught = []
326+
def thread_target():
327+
try:
328+
console.restore()
329+
except ValueError as e:
330+
if "signal only works in main thread" in str(e):
331+
exception_caught.append(e)
332+
thread = threading.Thread(target=thread_target)
333+
thread.start()
334+
thread.join()
335+
self.assertEqual(len(exception_caught), 0,
336+
"restore() should not raise ValueError in non-main thread")
337+
320338

321339
@unittest.skipIf(sys.platform == "win32", "No Unix console on Windows")
322340
class TestUnixConsoleEIOHandling(TestCase):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash in PyREPL asyncio mode when using Ctrl+Z (suspend) followed by
2+
``fg`` (resume).

0 commit comments

Comments
 (0)