12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- from __future__ import annotations
- import io
- import sys
- from typing import ContextManager, TextIO
- from .base import DummyInput, Input, PipeInput
- __all__ = [
- "create_input",
- "create_pipe_input",
- ]
- def create_input(stdin: TextIO | None = None, always_prefer_tty: bool = False) -> Input:
- """
- Create the appropriate `Input` object for the current os/environment.
- :param always_prefer_tty: When set, if `sys.stdin` is connected to a Unix
- `pipe`, check whether `sys.stdout` or `sys.stderr` are connected to a
- pseudo terminal. If so, open the tty for reading instead of reading for
- `sys.stdin`. (We can open `stdout` or `stderr` for reading, this is how
- a `$PAGER` works.)
- """
- if sys.platform == "win32":
- from .win32 import Win32Input
- # If `stdin` was assigned `None` (which happens with pythonw.exe), use
- # a `DummyInput`. This triggers `EOFError` in the application code.
- if stdin is None and sys.stdin is None:
- return DummyInput()
- return Win32Input(stdin or sys.stdin)
- else:
- from .vt100 import Vt100Input
- # If no input TextIO is given, use stdin/stdout.
- if stdin is None:
- stdin = sys.stdin
- if always_prefer_tty:
- for obj in [sys.stdin, sys.stdout, sys.stderr]:
- if obj.isatty():
- stdin = obj
- break
- # If we can't access the file descriptor for the selected stdin, return
- # a `DummyInput` instead. This can happen for instance in unit tests,
- # when `sys.stdin` is patched by something that's not an actual file.
- # (Instantiating `Vt100Input` would fail in this case.)
- try:
- stdin.fileno()
- except io.UnsupportedOperation:
- return DummyInput()
- return Vt100Input(stdin)
- def create_pipe_input() -> ContextManager[PipeInput]:
- """
- Create an input pipe.
- This is mostly useful for unit testing.
- Usage::
- with create_pipe_input() as input:
- input.send_text('inputdata')
- Breaking change: In prompt_toolkit 3.0.28 and earlier, this was returning
- the `PipeInput` directly, rather than through a context manager.
- """
- if sys.platform == "win32":
- from .win32_pipe import Win32PipeInput
- return Win32PipeInput.create()
- else:
- from .posix_pipe import PosixPipeInput
- return PosixPipeInput.create()
|