python / python/cpython

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

Ouverte
#128,424 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

OS-windows topic-subprocess type-bug
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

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:
https://github.com/python/cpython/blob/067145177975eadd61a0c907d0d177f7b6a5a3de/Lib/subprocess.py#L1398
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

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez dans Lib/subprocess.py, autour de la ligne 1398 indiquée par le lien, et reproduisez le cas parent.py/child.py sous Windows avec pythonw.exe et CREATE_NEW_CONSOLE. C’est terminé lorsque Popen peut rediriger stdin et stdout tout en laissant sélectivement stderr comme handle par défaut, y compris lorsque le parent est un script GUI.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
operating-systems
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.