You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Windows: new REPL loops forever on OSError from getheightwidth when stdin is NUL and output is redirected #159323
On Windows, when stdin is the NUL device and stdout/stderr are redirected to a file or pipe, starting the interpreter with no script enters the new REPL (because NUL reports isatty() as True), and the REPL then raises OSError: [WinError 123] from WindowsConsole.getheightwidth() on every prompt, forever. It never exits and writes tracebacks as fast as it can.
Reproduction (Git Bash; the same happens from any shell that gives the process NUL as stdin and a non-console stdout, e.g. agent or CI harnesses):
File "...\Lib\_pyrepl\windows_console.py", line 354, in prepare
self.height, self.width = self.getheightwidth()
File "...\Lib\_pyrepl\windows_console.py", line 405, in getheightwidth
raise WinError(GetLastError())
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect.
python -c "import sys; print(sys.stdin.isatty())" < NUL prints True.
With PYTHON_BASIC_REPL=1 the same command prints the banner, reads EOF and exits 0 at once.
Expected: when the console size (or any console API) is unavailable, the REPL should fall back to the basic REPL or exit on EOF, not retry the failing prompt in an endless loop.
Related: tox-dev/tox#3635 hit the same WinError 123 from getheightwidth (closed there, not reported here); #133430 looked similar but was closed as user error.
CPython versions tested on:
3.14
Operating systems tested on:
Windows
Python 3.14.7 (tags/v3.14.7:823f032, Aug 5 2026, 10:51:32) [MSC v.1944 64 bit (AMD64)], Windows 11 Home 10.0.26200.
Thanks for looking! Nobody starts the interactive REPL on purpose with stdin set to NUL. The trouble is that tools which run commands non-interactively hand the process NUL as stdin, and since NUL is a character device, isatty() reports True. So an accidental bare python, or python - with an empty heredoc, lands in pyrepl instead of reading EOF and exiting.
Where I hit it: AI coding agents. Claude Code's shell tool on Windows runs every command with stdin = NUL and output captured, so anyone using it on Windows can hit this. The process never returns: it spins writing tracebacks (about 4 MB in 3 seconds here) until the tool's timeout kills it. hyperfine also defaults stdin to NUL (that's how #133430 got there), and CI runners and schedulers commonly do the same.
The basic REPL (PYTHON_BASIC_REPL=1) reads EOF and exits at once, which is what these tools need.
A possible check: GetConsoleMode fails on NUL even though isatty() succeeds:
Activity
edvilme commentedon Oct 13, 2026
Hi. I would love to take a look but is there a real life case scenario in which to use stdin NUL for the interactive REPL?
lucaderosa2-jpg commentedon Oct 13, 2026
Thanks for looking! Nobody starts the interactive REPL on purpose with stdin set to NUL. The trouble is that tools which run commands non-interactively hand the process NUL as stdin, and since NUL is a character device,
isatty()reports True. So an accidental barepython, orpython -with an empty heredoc, lands in pyrepl instead of reading EOF and exiting.Where I hit it: AI coding agents. Claude Code's shell tool on Windows runs every command with stdin = NUL and output captured, so anyone using it on Windows can hit this. The process never returns: it spins writing tracebacks (about 4 MB in 3 seconds here) until the tool's timeout kills it. hyperfine also defaults stdin to NUL (that's how #133430 got there), and CI runners and schedulers commonly do the same.
The basic REPL (
PYTHON_BASIC_REPL=1) reads EOF and exits at once, which is what these tools need.A possible check:
GetConsoleModefails on NUL even thoughisatty()succeeds:So pyrepl could fall back to the basic REPL when
GetConsoleModefails on stdin, or at least stop retrying after the firstOSErrorfromgetheightwidth.Locked-chess-official commentedon Oct 14, 2026
You can use this command to see it: