prompt-toolkit / prompt-toolkit/python-prompt-toolkit

OSError: [Errno 22] Invalid argument, whenever getting input after PIPE in

Open
#1,943 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
10.6k
Forks
815
PR merge metrics
No merged PRs in 30d

Description

Hello team,

Thank you for the useful library!

I have an issue I would like to report.
The below code works if we replace the prompt_toolkit's prompt() with simple input(). I would like to have the ability to accept input after the user piped in some content. But it fails whenever using prompt toolkit in this scenario.

"""
Minimal example demonstrating prompt_toolkit issue with reopened TTY.
Run with: echo "test" | python minimal_tty_issue.py
"""
import sys
from prompt_toolkit import prompt

def main():
    # Simulate piped input scenario
    if not sys.stdin.isatty():
        content = sys.stdin.read()
        print(f"Got from pipe: {content}")
        
        # Reopen TTY - this causes the issue
        sys.stdin = open('/dev/tty', 'r')

    # Try to get interactive input
    user_input = prompt("")
    print(f"Got interactively: {user_input}")

if __name__ == "__main__":
    main()
❯ echo "test" | python minimal_tty_issue.py
Got from pipe: test

Traceback (most recent call last):
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/asyncio/selector_events.py", line 269, in _add_reader
    key = self._selector.get_key(fd)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/selectors.py", line 192, in get_key
    raise KeyError("{!r} is not registered".format(fileobj)) from None
KeyError: '3 is not registered'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/kostard/personal/HermesExperiments/cli/input/minimal_tty_issue.py", line 22, in <module>
    main()
  File "/Users/kostard/personal/HermesExperiments/cli/input/minimal_tty_issue.py", line 18, in main
    user_input = prompt("")
                 ^^^^^^^^^^
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/site-packages/prompt_toolkit/shortcuts/prompt.py", line 1425, in prompt
    return session.prompt(
           ^^^^^^^^^^^^^^^
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/site-packages/prompt_toolkit/shortcuts/prompt.py", line 1035, in prompt
    return self.app.run(
           ^^^^^^^^^^^^^
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/site-packages/prompt_toolkit/application/application.py", line 1002, in run
    return asyncio.run(coro)
           ^^^^^^^^^^^^^^^^^
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/asyncio/base_events.py", line 654, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/site-packages/prompt_toolkit/application/application.py", line 886, in run_async
    return await _run_async(f)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/site-packages/prompt_toolkit/application/application.py", line 734, in _run_async
    with self.input.raw_mode(), self.input.attach(
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/site-packages/prompt_toolkit/input/vt100.py", line 165, in _attached_input
    loop.add_reader(fd, callback_wrapper)
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/asyncio/selector_events.py", line 344, in add_reader
    self._add_reader(fd, callback, *args)
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/asyncio/selector_events.py", line 271, in _add_reader
    self._selector.register(fd, selectors.EVENT_READ,
  File "/Users/kostard/.local/share/mise/installs/python/3.11/lib/python3.11/selectors.py", line 523, in register
    self._selector.control([kev], 0, 0)
OSError: [Errno 22] Invalid argument

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the minimal_tty_issue.py example with the shown piped command. Then inspect prompt_toolkit/input/vt100.py at _attached_input and the application run path shown in the traceback, focusing on reopening /dev/tty after reading piped input. Done means prompt() accepts interactive input after the pipe without the OSError.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.