python / cpython

The Python programming language
https://www.python.org
Other
62.2k stars 29.89k forks source link

subprocess documentation incorrectly implies text-mode translation options apply to files #99864

Open cemysce opened 1 year ago

cemysce commented 1 year ago

Documentation

The documentation for the subprocess module (I'm looking at both 3.8 and 3.11) makes the following misleading or inaccurate claims (excerpts taken from 3.11, but similar statements exist in both):

In reality, even if text mode is enabled (as required by the above statements) these translations only occur for a stream (stdin, stdout, or stderr) if that stream is specified as or implied to be subprocess.PIPE. It's not clear to a reader that if they pass a file object (for instance a TextIOWrapper) for a stream, the encapsulation (i.e. translation features) provided by that file object is completely circumvented because subprocess actually just passes the underlying file descriptor directly to the child process.

There are also issues with phrases like "file objects ... stdin, stdout and stderr ... opened in text mode" (variations of this appear a few times):

Just to be clear, I think the actual implementation of subprocess is totally reasonable. Otherwise, subprocess would have to use a pipe under the hood. Then if stdin was passed a file object, subprocess would have to read from the file object, performing appropriate translations, then write to a pipe, and pass the pipe's read fd as the child's stdin. And if stdout/stderr was passed a file object, subprocess would have to pass a pipe's write fd as the child's stdout/stderr, then read from that pipe, and perform translations when writing to the file object. All this functionality is best implemented by the application itself.

My issue is just about the documentation, which implies the above functionality when in fact all translation is bypassed.

cemysce commented 1 year ago

FYI I came across this issue because I was investigating a program I'm calling with subprocess.run on Windows, whose stderr I'm directing to a file. (It happens to be a Python program, though I don't think that actually matters here.) The program has its own bug, whereby it prints to stderr with '\n' line terminators, regardless of the platform on which it is running.

So I was expecting to be able to use pass the file object (which is actually a TextIOWrapper with appropriate value for newline) to subprocess.run and have the line endings seamlessly translated.