Skip to content

fix(bash): decode Windows command output in Python's UTF-8 mode - #3897

Merged
zhayujie merged 1 commit into
zhayujie:masterfrom
b84330808:fix/bash-decode-utf8-mode
Nov 4, 2026
Merged

zhayujie merged 1 commit into
zhayujie:masterfrom
b84330808:fix/bash-decode-utf8-mode

Conversation

@b84330808

Copy link
Copy Markdown
Contributor

What does this PR do?

decode_output() falls back to the Windows code page when a command's output is not valid UTF-8. It looks that code page up with locale.getpreferredencoding(False). In Python's UTF-8 mode (PYTHONUTF8=1, -X utf8, and the default from Python 3.15) that always returns "utf-8", so the fallback is skipped and code-page output comes back as mojibake.

On a cp932 system with -X utf8, echo テスト through cmd.exe decodes as '�e�X�g\r\n' instead of 'テスト\r\n'. Without UTF-8 mode it decodes correctly. On Chinese Windows the same happens with cp936/GBK output.

The fix uses locale.getencoding() (Python 3.11+), which returns the code page regardless of UTF-8 mode, and keeps getpreferredencoding() for older Pythons.

tests/test_bash_decode_utf8_mode.py simulates UTF-8 mode on a cp936 system. The GBK case fails without the change and passes with it. The existing tests/test_bash_*.py files still pass (88 passed, 31 skipped on Windows, Python 3.11).

Type of change

  • Bug fix
  • New feature
  • Docs
  • Refactor / chore

Checklist

  • I have read the Contributing Guide
  • I tested this change locally
  • Code comments and docs are in English
  • Linked related issue (if any): closes #

I used Claude Code to write this change.

decode_output() falls back to the Windows code page when a command's output
is not valid UTF-8, and looked that code page up with
locale.getpreferredencoding(). In UTF-8 mode (PYTHONUTF8=1, -X utf8, and the
default from Python 3.15) that always returns "utf-8", so the fallback was
skipped and GBK output came back as mojibake. Use locale.getencoding() when
it exists; it returns the code page regardless of UTF-8 mode.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@zhayujie

zhayujie commented Nov 4, 2026

Copy link
Copy Markdown
Owner

Thanks! UTF-8 mode quietly skipping the code-page fallback is a subtle one, and locale.getencoding() with the older-Python fallback is exactly right. Merging.

@zhayujie
zhayujie merged commit fb944f8 into zhayujie:master Nov 4, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants