| 30 | |
| 31 | |
| 32 | class EchoingStdin: |
| 33 | _input: t.BinaryIO |
| 34 | _output: t.BinaryIO |
| 35 | _paused: bool |
| 36 | |
| 37 | def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None: |
| 38 | self._input = input |
| 39 | self._output = output |
| 40 | self._paused = False |
| 41 | |
| 42 | def __getattr__(self, x: str) -> t.Any: |
| 43 | return getattr(self._input, x) |
| 44 | |
| 45 | def _echo(self, rv: bytes) -> bytes: |
| 46 | if not self._paused: |
| 47 | self._output.write(rv) |
| 48 | |
| 49 | return rv |
| 50 | |
| 51 | def read(self, n: int = -1) -> bytes: |
| 52 | return self._echo(self._input.read(n)) |
| 53 | |
| 54 | def read1(self, n: int = -1) -> bytes: |
| 55 | return self._echo(self._input.read1(n)) # type: ignore |
| 56 | |
| 57 | def readline(self, n: int = -1) -> bytes: |
| 58 | return self._echo(self._input.readline(n)) |
| 59 | |
| 60 | def readlines(self) -> list[bytes]: |
| 61 | return [self._echo(x) for x in self._input.readlines()] |
| 62 | |
| 63 | def __iter__(self) -> cabc.Iterator[bytes]: |
| 64 | return iter(self._echo(x) for x in self._input) |
| 65 | |
| 66 | def __repr__(self) -> str: |
| 67 | return repr(self._input) |
| 68 | |
| 69 | |
| 70 | @contextlib.contextmanager |