{"id":"e4a93de36eaa66d5","repo":"pytest-dev/pytest","slug":"pytest-reading-from-stdin-while-output-is-capture","errorCode":null,"errorMessage":"pytest: reading from stdin while output is captured!  Consider using `-s`.","messagePattern":"pytest: reading from stdin while output is captured!  Consider using `-s`\\.","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"error","filePath":"src/_pytest/capture.py","lineNumber":229,"sourceCode":"\nclass TeeCaptureIO(CaptureIO):\n    def __init__(self, other: TextIO) -> None:\n        self._other = other\n        super().__init__()\n\n    def write(self, s: str) -> int:\n        super().write(s)\n        return self._other.write(s)\n\n\nclass DontReadFromInput(TextIO):\n    @property\n    def encoding(self) -> str:\n        assert sys.__stdin__ is not None\n        return sys.__stdin__.encoding\n\n    def read(self, size: int = -1) -> str:\n        raise OSError(\n            \"pytest: reading from stdin while output is captured!  Consider using `-s`.\"\n        )\n\n    readline = read\n\n    def __next__(self) -> str:\n        return self.readline()\n\n    def readlines(self, hint: int | None = -1) -> list[str]:\n        raise OSError(\n            \"pytest: reading from stdin while output is captured!  Consider using `-s`.\"\n        )\n\n    def __iter__(self) -> Iterator[str]:\n        return self\n\n    def fileno(self) -> int:\n        raise UnsupportedOperation(\"redirected stdin is pseudofile, has no fileno()\")","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/capture.py#L211-L247","documentation":"DontReadFromInput.read raises OSError because pytest replaces sys.stdin with a pseudo-file while output capturing is active (default). Reading from stdin in a test would hang waiting for input that never comes, so pytest forbids it.","triggerScenarios":"In a test (or fixture) under default capture mode, call sys.stdin.read() or input() (which uses stdin.readline). The DontReadFromInput proxy raises OSError.","commonSituations":"Code under test calls input() to prompt a user; a CLI function reads stdin unconditionally; a library probes sys.stdin.read() at import time.","solutions":["Run pytest with -s (or --capture=no) to disable stdin replacement so real stdin is used.","Refactor the code under test to accept input via a parameter or an injected file object instead of reading stdin directly.","Use monkeypatch.setattr('sys.stdin', io.StringIO('data')) to feed deterministic input.","Use the capsys/capfd monkeypatching patterns or pytest's monkeypatch to inject a fake stdin."],"exampleFix":"// before\n# test calls code that does: data = sys.stdin.read()\n// after\n$ pytest -s\n# or in the test:\nmonkeypatch.setattr('sys.stdin', io.StringIO('hello'))","handlingStrategy":"validation","validationCode":"import sys\n\ndef safe_read_stdin():\n    if not sys.stdin.isatty() and 'DontReadFromInput' in type(sys.stdin).__name__:\n        raise RuntimeError('stdin is captured; run pytest with -s or inject input')\n    return sys.stdin.read()","typeGuard":"def is_captured_stdin(stream) -> bool:\n    return type(stream).__name__ == 'DontReadFromInput'","tryCatchPattern":"try:\n    data = sys.stdin.read()\nexcept OSError as e:\n    if 'reading from stdin' in str(e):\n        # fall back: no input available under capture\n        data = ''\n    else:\n        raise","preventionTips":["Inject input via monkeypatch.setattr('sys.stdin', io.StringIO(...)) in tests rather than reading real stdin.","Run pytest with -s for any test that legitimately needs interactive stdin.","Refactor production code to accept an input stream as a parameter."],"tags":["pytest","capture","stdin","io"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}