@@ -53,6 +53,42 @@ def runcode(self, code: types.CodeType) -> None:
5353 # We always use sys.excepthook, unlike other implementations.
5454 # This means that overriding self.write also does nothing to tbs.
5555 sys .excepthook (sys .last_type , sys .last_value , sys .last_traceback )
56+ # clear any residual KI
57+ trio .from_thread .run (trio .lowlevel .checkpoint_if_cancelled )
58+ # trio.from_thread.check_cancelled() has too long of a memory
59+
60+ if sys .platform == "win32" :
61+
62+ def raw_input (self , prompt : str = "" ) -> str :
63+ try :
64+ return input (prompt )
65+ except EOFError :
66+ # check if trio has a pending KI
67+ trio .from_thread .run (trio .lowlevel .checkpoint_if_cancelled )
68+ raise
69+
70+ else :
71+
72+ def raw_input (self , prompt : str = "" ) -> str :
73+ import fcntl
74+ import termios
75+ from signal import SIGINT , signal
76+
77+ interrupted = False
78+
79+ def handler (sig : int , frame : types .FrameType | None ) -> None :
80+ nonlocal interrupted
81+ 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 " )
84+
85+ prev_handler = trio .from_thread .run_sync (signal , SIGINT , handler )
86+ try :
87+ return input (prompt )
88+ finally :
89+ trio .from_thread .run_sync (signal , SIGINT , prev_handler )
90+ if interrupted :
91+ raise KeyboardInterrupt
5692
5793
5894async def run_repl (console : TrioInteractiveConsole ) -> None :
0 commit comments