Skip to content

Commit be4ccdf

Browse files
tornariajonathanslenders
authored andcommitted
Restore signal.SIGINT handler between prompts
1 parent 6e4ca6e commit be4ccdf

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

src/prompt_toolkit/application/application.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
sleep,
1818
)
1919
from contextlib import ExitStack, contextmanager
20+
from ctypes import c_int, c_void_p, pythonapi
2021
from subprocess import Popen
2122
from traceback import format_tb
2223
from typing import (
@@ -102,6 +103,21 @@
102103
_SIGTSTP = getattr(signal, "SIGTSTP", None)
103104

104105

106+
# The following functions are part of the stable ABI since python 3.2
107+
# See: https://docs.python.org/3/c-api/sys.html#c.PyOS_getsig
108+
109+
# PyOS_sighandler_t PyOS_getsig(int i)
110+
pythonapi.PyOS_getsig.restype = c_void_p
111+
pythonapi.PyOS_getsig.argtypes = (c_int,)
112+
113+
# PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h)
114+
pythonapi.PyOS_setsig.restype = c_void_p
115+
pythonapi.PyOS_setsig.argtypes = (
116+
c_int,
117+
c_void_p,
118+
)
119+
120+
105121
class Application(Generic[_AppResult]):
106122
"""
107123
The main Application class!
@@ -807,6 +823,10 @@ def set_is_running() -> Iterator[None]:
807823
@contextmanager
808824
def set_handle_sigint(loop: AbstractEventLoop) -> Iterator[None]:
809825
if handle_sigint:
826+
# save sigint handlers (python and os level)
827+
# See: https://github.com/prompt-toolkit/python-prompt-toolkit/issues/1576
828+
sigint = signal.getsignal(signal.SIGINT)
829+
sigint_os = pythonapi.PyOS_getsig(signal.SIGINT)
810830
loop.add_signal_handler(
811831
signal.SIGINT,
812832
lambda *_: loop.call_soon_threadsafe(
@@ -817,6 +837,8 @@ def set_handle_sigint(loop: AbstractEventLoop) -> Iterator[None]:
817837
yield
818838
finally:
819839
loop.remove_signal_handler(signal.SIGINT)
840+
signal.signal(signal.SIGINT, sigint)
841+
pythonapi.PyOS_setsig(signal.SIGINT, sigint_os)
820842
else:
821843
yield
822844

0 commit comments

Comments
 (0)