Skip to content

Commit a5dcdbf

Browse files
apply suggestion from review, ensure calls in handler are safe
1 parent 46a3f02 commit a5dcdbf

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

src/trio/_repl.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
from trio._util import final
1616

1717

18+
class SuppressDecorator(contextlib.ContextDecorator, contextlib.suppress):
19+
pass
20+
21+
1822
@final
1923
class TrioInteractiveConsole(InteractiveConsole):
2024
# code.InteractiveInterpreter defines locals as Mapping[str, Any]
@@ -24,6 +28,7 @@ class TrioInteractiveConsole(InteractiveConsole):
2428

2529
def __init__(self, repl_locals: dict[str, object] | None = None) -> None:
2630
super().__init__(locals=repl_locals)
31+
self.token: trio.lowlevel.TrioToken | None = None
2732
self.compile.compiler.flags |= ast.PyCF_ALLOW_TOP_LEVEL_AWAIT
2833

2934
def runcode(self, code: types.CodeType) -> None:
@@ -70,17 +75,26 @@ def raw_input(self, prompt: str = "") -> str:
7075
else:
7176

7277
def raw_input(self, prompt: str = "") -> str:
73-
import fcntl
74-
import termios
7578
from signal import SIGINT, signal
7679

7780
interrupted = False
7881

82+
if self.token is None:
83+
self.token = trio.from_thread.run_sync(trio.lowlevel.current_trio_token)
84+
85+
@SuppressDecorator(KeyboardInterrupt)
86+
@trio.lowlevel.disable_ki_protection
87+
def newline():
88+
import fcntl
89+
import termios
90+
91+
# Fake up a newline char as if user had typed it at
92+
fcntl.ioctl(sys.stdin, termios.TIOCSTI, b"\n")
93+
7994
def handler(sig: int, frame: types.FrameType | None) -> None:
8095
nonlocal interrupted
8196
interrupted = True
82-
# Fake up a newline char as if user had typed it at terminal
83-
fcntl.ioctl(sys.stdin, termios.TIOCSTI, b"\n")
97+
self.token.run_sync_soon(newline, idempotent=True)
8498

8599
prev_handler = trio.from_thread.run_sync(signal, SIGINT, handler)
86100
try:

0 commit comments

Comments
 (0)