Skip to content

subprocess.Popen() should allow capturing output and sending it to stdout and stderr #91378

Closed as not planned

Description

@pprindeville
BPO 47222
Nosy @gpshead, @pprindeville
PRs
  • gh-91378: Allow subprocess pass-thru with stdout/stderr capture #32344
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2022-04-04.22:52:49.296>
    labels = ['type-feature', 'library', '3.11']
    title = 'subprocess.Popen() should allow capturing output and sending it to stdout and stderr'
    updated_at = <Date 2022-04-05.21:08:52.185>
    user = 'https://github.com/pprindeville'

    bugs.python.org fields:

    activity = <Date 2022-04-05.21:08:52.185>
    actor = 'pprindeville'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2022-04-04.22:52:49.296>
    creator = 'pprindeville'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 47222
    keywords = ['patch']
    message_count = 1.0
    messages = ['416703']
    nosy_count = 2.0
    nosy_names = ['gregory.p.smith', 'pprindeville']
    pr_nums = ['32344']
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue47222'
    versions = ['Python 3.11']

    Activity

    1. pprindeville commented on Apr 4, 2022

      pprindevillemannequin
      MannequinAuthor

      I'd like to see handlers exposes for the stdout and stderr pipe-reading threads so that I could customize what's done with the data as it's read.

      I might, for instance, want to:

      (1) accumulate it into a buffer;
      (2) copy it onto sys.stdout or sys.stderr, respectively;
      (3) send it to a logging object;

      or some combination of the above, possibly all of them.

    2. added
      3.11only security fixes
      stdlibStandard Library Python modules in the Lib/ directory
      type-featureA feature request or enhancement
      on Apr 4, 2022
    3. transferred this issue fromon Apr 10, 2022
    4. 54 remaining items

    5. gerion0 commented on Oct 7, 2024

      @gerion0

      I wanted to request the same and had a hard time to find this issue (while this issue/PR is more advanced). I searched for subprocess and tee. This word is mentioned in the PR but not here. Therefore I want to leave it here to make searching easier:
      "Provide a tee-mode for subprocess.Popen with stdout or stderr set to something other than None and subprocess.run with capture_output=True"

    6. lyricaljoke commented on Nov 6, 2024

      @lyricaljoke

      This would be useful to have. IMO it would be best to support this generically by fully supporting using file-like objects as the stdout, stderr, arguments. Developers could then pass in a file-like object which forwards writes to one or more locations (e.g. a string buffer and stdout). The existing interface nearly supports this by accepting certain types of file-like objects (e.g. io.StringIO, io.BytesIO etc.), but it currently only works if the file-like object actually exposes a file descriptor via the fileno() method. I have observed that this often leads to developers poorly reinventing Popen.communicate() in application code.

      This limitation was noted long ago in #74175, but that issue only resulted in a fix to documentation.

    7. gpshead commented on Nov 7, 2024

      @gpshead
      Member

      I don't doubt the utility, it is something some applications want to do (I've done it multiple times over the years as well). But I'm not convinced we want to maintain such an ability within subprocess in the standard library itself. It adds complexity and being so abstract, would be a less than ideal implementation in many circumstances that the subprocess API caller may not be the best one to express in the context of a larger application. (async or not, threads or not, intermediate tee process or not, etc.)

      Design philosophy: subprocess today straddles the boundary between low level and high level. Providing a mostly platform agnostic way to create and manage a child process.

      The reason a file descriptor from .fileno() is required on stdin/out/err is because that is what the underlying OSes allow for connecting pipes behind the scenes so that the data flow is handled entirely by the OS without the current process being involved or even needing to exist. To support something otherwise requires us to re-invent the wheel of how to babysit pipes and copy & feed data from one place to another without blocking.

      Implementation wise: This ends up requiring threads for the general case. I'd rather not have the subprocess module spawn threads of its own for that behind the scenes on POSIX platforms where the existence of threads can have application wide consequences (it already does spawn threads on Windows internally for .communicate() to read pipes due to a lack of event driven IO). Supporting connections to arbitrary objects supporting read or write methods would require threads regardless of if there could be more efficient ways for specific users to meet their applications particular needs.

    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

      stdlibStandard Library Python modules in the Lib/ directorytopic-subprocessSubprocess issues.type-featureA feature request or enhancement

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions