GeezerVison is showing github.com — gh-158633: say that subprocess text mode guesses the child's encoding by AlKor13 · Pull Request #158634 · python/cpython
Conversation
AlKor13
commented
Oct 3, 2026
•
edited by bedevere-app
Bot
Loading
Uh oh!
There was an error while loading. Please reload this page.
Documentation only. Closes #158633, and implements what @zooba described on #105312:
I would add a warning that it will guess the encoding of the child process and you'll get garbage if it guesses wrong, and you are always recommended to specify the encoding to use (on all platforms, though you are most likely to get into trouble on Windows).
One .. warning:: in frequently-used-arguments, after the paragraph on binary mode. Popen's section already refers to that one, so it is covered too.
Two things the current text leaves out, and the reason they are worth a warning rather than a note:
-
Where the failure appears. When the guess is wrong the output is either silently mojibake, or a UnicodeDecodeError raised while the stream is read — and that traceback comes from inside subprocess, not from the call that omitted encoding=, which is what sends people looking for a bug in the module.
-
Windows has more than one default at once. Measured on Windows 11, ANSI code page cp1251, console output code page cp866, so two children of one process need two different decoders:
subprocess.run([sys.executable, "-c", "print('Тест')"], capture_output=True, text=True).stdout
# 'Тест' — the child wrote UTF-8
subprocess.run("echo Тест", shell=True, text=True, stdout=subprocess.PIPE).stdout
# '’Ґбв' — the child wrote cp866
Under UTF-8 mode, which :pep:686 makes the default in 3.15, the second becomes UnicodeDecodeError: 'utf-8' codec can't decode byte 0x92 rather than correct text — so the advice holds after 3.15, which is why the warning says so explicitly instead of presenting UTF-8 as the end of the problem.
The Windows paragraph keeps to @zooba's caveat that GetConsoleOutputCP is only right if you know the child uses it: it says a console program is read with that page, and that a Python child can instead be told what to write through PYTHONUTF8 / PYTHONIOENCODING in its env, which is knowledge rather than a guess.
No behaviour change and no new API, so I believe this is skip news; happy to add a blurb if you would rather have one. I have not signed the CLA yet — doing that now, and I will confirm here once it shows.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
…coding
Text mode documents which encoding is used and not that the value is a guess
about the child process, so a wrong guess reads as a bug in this module: the
output is either silently mojibake, or a UnicodeDecodeError raised while the
stream is read, reported from inside subprocess rather than from the call that
is missing encoding=.
The warning keeps to what was asked for on pythongh-105312: the default is a guess,
pass encoding= on every platform, and on Windows more than one default is in
force at once -- the ANSI code page and the console output code page -- so a
console child is read with the console page while a Python child can be told
what to write through PYTHONUTF8 / PYTHONIOENCODING.
|
All commit authors signed the Contributor License Agreement.

|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
CLA signed — the check is green now, and so are lint, Docs, Check EPUB, the HTML-ID check and the docs preview.
Rendered warning, for review without a local build: https://cpython-previews--158634.org.readthedocs.build/en/158634/library/subprocess.html#frequently-used-arguments — the five cross-references in it (UnicodeDecodeError, :pep:686, locale.getpreferredencoding, PYTHONUTF8, PYTHONIOENCODING) all resolve.
Happy to trim it if it reads long for one admonition; the Windows paragraph is the part I would cut first, since the first one carries the advice on its own.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Yeah, it's a bit wordy, and also sounds like it was AI written (perhaps by accident, but making it sound more casual would be more in line with the rest of our docs and we'd prefer it that way).
It's also not a "guess" - it's an arbitrary default that has no knowledge of what the child process intends to do. When UTF-8 mode is enabled, the guess is always UTF-8, and since that's the default for Python on all platforms now, it's really the only "guess" we care about. If the child process is not going to output UTF-8, the caller needs to override the encoding.
|
StanFromIreland reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|