Skip to content

Commit 163c9bc

Browse files
Fix sigint on Python 3.5+
1 parent 17367a5 commit 163c9bc

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

curtsies/input.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ def __enter__(self) -> "Input":
109109
if self.sigint_event and is_main_thread():
110110
self.orig_sigint_handler = signal.getsignal(signal.SIGINT)
111111
signal.signal(signal.SIGINT, self.sigint_handler)
112+
113+
self.wakeup_read_fd, wfd = os.pipe()
114+
os.set_blocking(wfd, False)
115+
if sys.version_info[0] == 3 and sys.version_info[1] > 4:
116+
signal.set_wakeup_fd(wfd, warn_on_full_buffer=False)
117+
112118
return self
113119

114120
def __exit__(
@@ -123,6 +129,8 @@ def __exit__(
123129
and self.orig_sigint_handler is not None
124130
):
125131
signal.signal(signal.SIGINT, self.orig_sigint_handler)
132+
if sys.version_info[0] == 3 and sys.version_info[1] > 4:
133+
signal.set_wakeup_fd(-1)
126134
termios.tcsetattr(self.in_stream, termios.TCSANOW, self.original_stty)
127135

128136
def sigint_handler(
@@ -158,13 +166,25 @@ def _wait_for_read_ready_or_timeout(
158166
while True:
159167
try:
160168
(rs, _, _) = select.select(
161-
[self.in_stream.fileno()] + self.readers, [], [], remaining_timeout
169+
[
170+
self.in_stream.fileno(),
171+
self.wakeup_read_fd,
172+
]
173+
+ self.readers,
174+
[],
175+
[],
176+
remaining_timeout,
162177
)
163178
if not rs:
164179
return False, None
165180
r = rs[0] # if there's more than one, get it in the next loop
166181
if r == self.in_stream.fileno():
167182
return True, None
183+
elif r == self.wakeup_read_fd:
184+
# In Python >=3.5 select won't raise this signal handler
185+
signal_number = ord(os.read(r, 1))
186+
if signal_number == signal.SIGINT:
187+
raise InterruptedError()
168188
else:
169189
os.read(r, 1024)
170190
if self.queued_interrupting_events:
@@ -217,7 +237,7 @@ def find_key() -> Optional[str]:
217237
return self.queued_interrupting_events.pop(0)
218238

219239
if self.queued_scheduled_events:
220-
self.queued_scheduled_events.sort() # TODO use a data structure that inserts sorted
240+
self.queued_scheduled_events.sort()
221241
when, _ = self.queued_scheduled_events[0]
222242
if when < time.time():
223243
logger.debug(

0 commit comments

Comments
 (0)