Skip to content

Inconsistent subprocess.Popen.communicate() behavior between Windows and Posix on non-byte memoryview input #134453

Closed

Description

@tikuma-lsuhsc

Bug report

Bug description:

This is not a bug per se as it diverges from the documentation, but Posix version of subprocess.Popen.communicate() behaves less ideally when a large "memoryview"-able object with non-byte item is passed as the input argument. For example, suppose I have a simple pass-through process which takes a long input array x of length greater than 512 and return it as is:

import subprocess as sp
import numpy as np

x = np.random.randn(44100, dtype=float) # 8-byte data type
ret = sp,run('pass_thru', input=x)
y = np.frombuffer(ret.stdout, dtype=float)
assert np.array_equal(x, y)

This example fails the assertion only in Posix because the returned array y shorter than x.

This appears to stem from sp.Popen.communicate()

if self._input:
    input_view = memoryview(self._input)

#[snip]

if key.fileobj is self.stdin:
    chunk = input_view[self._input_offset:self._input_offset + _PIPE_BUF]

    try:
        self._input_offset += os.write(key.fd, chunk)
    except BrokenPipeError:
        selector.unregister(key.fileobj)
        key.fileobj.close()
    else:
        if self._input_offset >= len(self._input):
            #[snip]

The indexed chunk of input_view sends more bytes if self._input is not a bytes-like while len(self._input) counts the number of items. As such self._input_offset > len(self._input) after the first few writes due to the mismatch in their units.

I think the if statement checks the bytes read against input_view.nbytes instead of len(self._input).

This use case is not officially supported as the input is expected to be bytes-like and not any arbitrary memoryview object, but it works under Windows, and this Posix codepath behavior is rather nasty as it works (as wrongly expected) for a short input (as is often the case for testing).

I believe an arbitrary memoryview object as a subprocess input works otherwise (based on my extensive uses passing audio and video data to and from FFmpeg) so perhaps I should label this issue as a feature request.

P.S., A fix for the example is to use ret = sp,run('pass_thru', input=x.view('b')).

CPython versions tested on:

3.13

Operating systems tested on:

No response

Linked PRs

Activity

  1. added
    stdlibStandard Library Python modules in the Lib/ directory
    on May 23, 2025
  2. changed the title [-]Inconsistent `subprocess.Popen.communicate()` behavior between Windows and Posix[/-] [+]Inconsistent `subprocess.Popen.communicate()` behavior between Windows and Posix on non-byte memoryview[/+] on May 30, 2025
  3. changed the title [-]Inconsistent `subprocess.Popen.communicate()` behavior between Windows and Posix on non-byte memoryview[/-] [+]Inconsistent `subprocess.Popen.communicate()` behavior between Windows and Posix on non-byte memoryview input[/+] on May 30, 2025
  4. self-assigned this
    on May 30, 2025
  5. added 2 commits that reference this issue on May 30, 2025
  6. gpshead commented on May 30, 2025

    @gpshead
    Member

    Thanks for the nice bug writeup. My PR leans into "well, why not" and fixes it as a bug because it already worked on one platform so we may as well make that behavior the definition of how it works.

  7. added a commit that references this issue on Nov 29, 2025
  8. added 2 commits that reference this issue on Nov 29, 2025
  9. gpshead commented on Nov 29, 2025

    @gpshead
    Member

    backports set to auto-merge.

  10. added 4 commits that reference this issue on Nov 29, 2025
  11. added a commit that references this issue on Dec 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

3.13only security fixes3.14bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytopic-subprocessSubprocess issues.type-bugAn unexpected behavior, bug, or error

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions