{"id":"442faef37eb9e7d2","repo":"pytest-dev/pytest","slug":"redirected-stdin-is-pseudofile-has-no-tell","errorCode":null,"errorMessage":"redirected stdin is pseudofile, has no tell()","messagePattern":"redirected stdin is pseudofile, has no tell\\(\\)","errorType":"exception","errorClass":"UnsupportedOperation","httpStatus":null,"severity":"warning","filePath":"src/_pytest/capture.py","lineNumber":268,"sourceCode":"        raise UnsupportedOperation(\"redirected stdin is pseudofile, has no flush()\")\n\n    def isatty(self) -> bool:\n        return False\n\n    def close(self) -> None:\n        pass\n\n    def readable(self) -> bool:\n        return False\n\n    def seek(self, offset: int, whence: int = 0) -> int:\n        raise UnsupportedOperation(\"redirected stdin is pseudofile, has no seek(int)\")\n\n    def seekable(self) -> bool:\n        return False\n\n    def tell(self) -> int:\n        raise UnsupportedOperation(\"redirected stdin is pseudofile, has no tell()\")\n\n    def truncate(self, size: int | None = None) -> int:\n        raise UnsupportedOperation(\"cannot truncate stdin\")\n\n    def write(self, data: str) -> int:\n        raise UnsupportedOperation(\"cannot write to stdin\")\n\n    def writelines(self, lines: Iterable[str]) -> None:\n        raise UnsupportedOperation(\"Cannot write to stdin\")\n\n    def writable(self) -> bool:\n        return False\n\n    def __enter__(self) -> Self:\n        return self\n\n    def __exit__(\n        self,","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/capture.py#L250-L286","documentation":"DontReadFromInput.tell() raises UnsupportedOperation because the captured stdin pseudo-file does not track a meaningful position. seekable()/readable() both return False.","triggerScenarios":"In a test under default capture, code calls sys.stdin.tell() — usually paired with seek for save/restore of stream position.","commonSituations":"Stream utilities that record position before parsing to restore later; logging libraries that report positions; copy-pasted file-handling code that treats stdin like a regular file.","solutions":["Run pytest with -s.","Refactor to read the whole stream into a buffer and track position yourself.","Guard tell() with a seekable() check."],"exampleFix":"// before\n# code: pos = sys.stdin.tell()\n// after\n# code: data = sys.stdin.read()  # manage offset in your own buffer","handlingStrategy":"type-guard","validationCode":"def safe_tell(stream):\n    if not getattr(stream, 'seekable', lambda: False)():\n        raise UnsupportedOperation('stream does not support tell')\n    return stream.tell()","typeGuard":"def is_seekable(stream) -> bool:\n    return bool(getattr(stream, 'seekable', lambda: False)())","tryCatchPattern":"from io import UnsupportedOperation\ntry:\n    pos = stream.tell()\nexcept (OSError, UnsupportedOperation, ValueError):\n    pos = -1","preventionTips":["Track stream positions in your own buffer for non-seekable sources.","Guard tell() with seekable()."],"tags":["pytest","capture","stdin","io"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}