Skip to content

subprocess.Popen on windows cannot use default handles for stdin/stdout/stderr when some of them are redirected #128424

Open
@panda-34

Description

Bug report

Bug description:

suppose I want to run a subprocess with piped stdin/stdout but let that process print to console using stderr (which is a common use pattern)
currently in Popen there's no way to override stdin=PIPE, stdout=PIPE but let stderr use default handle

if I have a child.py script:

import sys, time
try:
    print('console message', file=sys.stderr)
except Exception as e:
    open('CONOUT$', 'w').write(str(e))
while True:
    time.sleep(1)

and parent.py script:

import subprocess
with subprocess.Popen(('python.exe', 'child.py'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, creationflags=subprocess.CREATE_NEW_CONSOLE):
    pass

then it works if parent script is run in a console. But if it is a GUI script (e.g. run via pythonw.exe) then child script attempting to print to stderr gets [Errno 22] Invalid argument
this happens because this line:

errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE)

tries to inherit stderr, but it returns None in a GUI app, so then a fake Pipe is created and ultimately passed to CreateProcess as stderr instead of NULL handle.

Here's a hack which allows me to selectively pipe only stdin and stdout and leave stderr as default:

import subprocess

class HackedSTARTUPINFO(subprocess.STARTUPINFO):
    def __setattr__(self, attr, value):
        if attr == 'hStdError':
            value = None
        super().__setattr__(attr, value)

    def copy(self):
        return self

si = HackedSTARTUPINFO()
with subprocess.Popen(('python.exe', 'child.py'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, startupinfo=si, creationflags=subprocess.CREATE_NEW_CONSOLE):
    pass

This way child.py can print to stderr even if run from a GUI script.

There should be a way to selectively set STARTUPINFO.hStdInput/hStdOutput/hStdError to None using Popen arguments.

CPython versions tested on:

3.10

Operating systems tested on:

Windows

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions