Skip to content

Windows: new REPL loops forever on OSError from getheightwidth when stdin is NUL and output is redirected #159323

Open

Description

@lucaderosa2-jpg

Bug report

Bug description:

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):

timeout 3 python < /dev/null > out.txt 2>&1
wc -c out.txt           # 4,287,437 bytes after 3 seconds
grep -c Traceback out.txt   # 3,655

Each traceback ends:

  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.

Linked PRs

Activity

  1. edvilme commented on Oct 13, 2026

    @edvilme
    Contributor

    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?

  2. lucaderosa2-jpg commented on Oct 13, 2026

    @lucaderosa2-jpg
    Author

    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:

    isatty: True | GetFileType: 2 (char device) | GetConsoleMode ok: False
    

    So pyrepl could fall back to the basic REPL when GetConsoleMode fails on stdin, or at least stop retrying after the first OSError from getheightwidth.

  3. added
    type-bugAn unexpected behavior, bug, or error
    topic-replRelated to the interactive shell
    on Oct 13, 2026
  4. Locked-chess-official commented on Oct 14, 2026

    @Locked-chess-official
    Contributor

    You can use this command to see it:

    $a = python
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-windowstopic-replRelated to the interactive shelltype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions