|
17 | 17 | sleep,
|
18 | 18 | )
|
19 | 19 | from contextlib import ExitStack, contextmanager
|
20 |
| -from ctypes import c_int, c_void_p, pythonapi |
21 | 20 | from subprocess import Popen
|
22 | 21 | from traceback import format_tb
|
23 | 22 | from typing import (
|
|
103 | 102 | _SIGTSTP = getattr(signal, "SIGTSTP", None)
|
104 | 103 |
|
105 | 104 |
|
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 |
| - |
121 | 105 | class Application(Generic[_AppResult]):
|
122 | 106 | """
|
123 | 107 | The main Application class!
|
@@ -823,22 +807,19 @@ def set_is_running() -> Iterator[None]:
|
823 | 807 | @contextmanager
|
824 | 808 | def set_handle_sigint(loop: AbstractEventLoop) -> Iterator[None]:
|
825 | 809 | 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) |
830 |
| - loop.add_signal_handler( |
831 |
| - signal.SIGINT, |
832 |
| - lambda *_: loop.call_soon_threadsafe( |
833 |
| - self.key_processor.send_sigint |
834 |
| - ), |
835 |
| - ) |
836 |
| - try: |
837 |
| - yield |
838 |
| - finally: |
839 |
| - loop.remove_signal_handler(signal.SIGINT) |
840 |
| - signal.signal(signal.SIGINT, sigint) |
841 |
| - pythonapi.PyOS_setsig(signal.SIGINT, sigint_os) |
| 810 | + with _restore_sigint_from_ctypes(): |
| 811 | + # save sigint handlers (python and os level) |
| 812 | + # See: https://github.com/prompt-toolkit/python-prompt-toolkit/issues/1576 |
| 813 | + loop.add_signal_handler( |
| 814 | + signal.SIGINT, |
| 815 | + lambda *_: loop.call_soon_threadsafe( |
| 816 | + self.key_processor.send_sigint |
| 817 | + ), |
| 818 | + ) |
| 819 | + try: |
| 820 | + yield |
| 821 | + finally: |
| 822 | + loop.remove_signal_handler(signal.SIGINT) |
842 | 823 | else:
|
843 | 824 | yield
|
844 | 825 |
|
@@ -1609,3 +1590,36 @@ def attach_winch_signal_handler(
|
1609 | 1590 | previous_winch_handler._callback,
|
1610 | 1591 | *previous_winch_handler._args,
|
1611 | 1592 | )
|
| 1593 | + |
| 1594 | + |
| 1595 | +@contextmanager |
| 1596 | +def _restore_sigint_from_ctypes() -> Generator[None, None, None]: |
| 1597 | + # The following functions are part of the stable ABI since python 3.2 |
| 1598 | + # See: https://docs.python.org/3/c-api/sys.html#c.PyOS_getsig |
| 1599 | + # Inline import: these are not available on Pypy. |
| 1600 | + try: |
| 1601 | + from ctypes import c_int, c_void_p, pythonapi |
| 1602 | + except ImportError: |
| 1603 | + # Any of the above imports don't exist? Don't do anything here. |
| 1604 | + yield |
| 1605 | + return |
| 1606 | + |
| 1607 | + # PyOS_sighandler_t PyOS_getsig(int i) |
| 1608 | + pythonapi.PyOS_getsig.restype = c_void_p |
| 1609 | + pythonapi.PyOS_getsig.argtypes = (c_int,) |
| 1610 | + |
| 1611 | + # PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h) |
| 1612 | + pythonapi.PyOS_setsig.restype = c_void_p |
| 1613 | + pythonapi.PyOS_setsig.argtypes = ( |
| 1614 | + c_int, |
| 1615 | + c_void_p, |
| 1616 | + ) |
| 1617 | + |
| 1618 | + sigint = signal.getsignal(signal.SIGINT) |
| 1619 | + sigint_os = pythonapi.PyOS_getsig(signal.SIGINT) |
| 1620 | + |
| 1621 | + try: |
| 1622 | + yield |
| 1623 | + finally: |
| 1624 | + signal.signal(signal.SIGINT, sigint) |
| 1625 | + pythonapi.PyOS_setsig(signal.SIGINT, sigint_os) |
0 commit comments