Skip to content

Commit 6a24c99

Browse files
Fix for pypy: don't use pythonapi on pypy.
1 parent 1c6d094 commit 6a24c99

File tree

1 file changed

+46
-32
lines changed

1 file changed

+46
-32
lines changed

src/prompt_toolkit/application/application.py

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
sleep,
1818
)
1919
from contextlib import ExitStack, contextmanager
20-
from ctypes import c_int, c_void_p, pythonapi
2120
from subprocess import Popen
2221
from traceback import format_tb
2322
from typing import (
@@ -103,21 +102,6 @@
103102
_SIGTSTP = getattr(signal, "SIGTSTP", None)
104103

105104

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-
121105
class Application(Generic[_AppResult]):
122106
"""
123107
The main Application class!
@@ -823,22 +807,19 @@ def set_is_running() -> Iterator[None]:
823807
@contextmanager
824808
def set_handle_sigint(loop: AbstractEventLoop) -> Iterator[None]:
825809
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)
842823
else:
843824
yield
844825

@@ -1609,3 +1590,36 @@ def attach_winch_signal_handler(
16091590
previous_winch_handler._callback,
16101591
*previous_winch_handler._args,
16111592
)
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

Comments
 (0)