Skip to content

Commit 32cc3ec

Browse files
author
mads
committed
fix(vt100): treat OSError on add_reader as EOFError (macOS kqueue)
`Vt100Input._attached_input` already raises `EOFError` when `loop.add_reader(fd, ...)` fails with `PermissionError`, which is what Linux's `EPollSelector` raises when stdin points at /dev/null. macOS's `KqueueSelector` does not raise `PermissionError` for the same class of "unpollable stdin" cases — it raises `OSError [Errno 22] Invalid argument` (from `kqueue.control()`). This currently propagates all the way up out of `Application.run()` and crashes any consumer that expected the existing `EOFError` contract. Reproducer (macOS): python -c "from prompt_toolkit import prompt; prompt('> ')" \ 0< /dev/null Or any wrapper that launches a prompt_toolkit app with a non-TTY stdin on macOS — e.g. spawned from another agent process that has reassigned fd 0. Treat both `PermissionError` and `OSError` from `add_reader` as end-of-input and raise `EOFError`, so callers see the same exception regardless of which selector backend asyncio picked.
1 parent 940af53 commit 32cc3ec

1 file changed

Lines changed: 6 additions & 4 deletions

File tree

src/prompt_toolkit/input/vt100.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,14 @@ def callback_wrapper() -> None:
167167

168168
try:
169169
loop.add_reader(fd, callback_wrapper)
170-
except PermissionError:
170+
except (PermissionError, OSError):
171171
# For `EPollSelector`, adding /dev/null to the event loop will raise
172172
# `PermissionError` (that doesn't happen for `SelectSelector`
173-
# apparently). Whenever we get a `PermissionError`, we can raise
174-
# `EOFError`, because there's not more to be read anyway. `EOFError` is
175-
# an exception that people expect in
173+
# apparently). On macOS `KqueueSelector`, an unpollable stdin fd
174+
# (e.g. detached parent, /dev/null, or otherwise non-TTY) raises
175+
# `OSError [Errno 22] Invalid argument` instead. Both mean "nothing
176+
# more to read here", so we surface them as `EOFError`, which is an
177+
# exception people expect in
176178
# `prompt_toolkit.application.Application.run()`.
177179
# To reproduce, do: `ptpython 0< /dev/null 1< /dev/null`
178180
raise EOFError

0 commit comments

Comments
 (0)