fix: preserve ANSI colors when piping to pager on Windows#1705
fix: preserve ANSI colors when piping to pager on Windows#1705VoidChecksum wants to merge 2 commits intohttpie:masterfrom
Conversation
When stdout is piped (e.g. `http --pretty=all ... | less -r`), colorama detects a non-TTY stream and strips all ANSI escape codes. This makes `--pretty=all` output appear uncolored in pagers on Windows. Only route through `write_stream_with_colors_win()` when stdout is an actual terminal. When piped, fall through to `write_stream()` which writes raw bytes (including ANSI codes) directly to `outfile.buffer`, bypassing colorama's text-layer stripping. Fixes httpie#799
There was a problem hiding this comment.
Pull request overview
Fixes a Windows-specific color handling issue where --pretty=all output loses ANSI colors when stdout is piped to a pager by avoiding the colorama text wrapper when stdout is not a TTY.
Changes:
- Gate the Windows
write_stream_with_colors_win()path behindenv.stdout_isattyso it’s only used for real terminals. - Allow piped/redirected Windows output to go through
write_stream()(raw bytes), preserving ANSI escape sequences for pagers likeless -r.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| if env.is_windows and env.stdout_isatty and 'colors' in processing_options.get_prettify(env): | ||
| write_stream_with_colors_win(**write_stream_kwargs) | ||
| else: | ||
| write_stream(**write_stream_kwargs) |
There was a problem hiding this comment.
Add a regression test for this Windows-specific branch selection: when env.is_windows is true, colors are requested (e.g. --pretty=all), and env.stdout_isatty is false (piped/redirected), we should use the raw write_stream() path (and not write_stream_with_colors_win()) so ANSI escape codes are preserved. Without a test, this behavior is easy to accidentally regress and reintroduce the color-stripping issue reported in #799.
Verify that when stdout is piped on Windows (stdout_isatty=False), write_stream() is used instead of write_stream_with_colors_win(), ensuring ANSI escape codes pass through to pagers like `less -r`. Regression test for httpie#799.
Summary
Fixes #799 —
--pretty=alloutput loses colors when piped to a pager (less -r,more, etc.) on Windows.Root cause
On Windows, HTTPie wraps
stdoutthrough colorama to translate ANSI escape codes into Win32 console API calls. When stdout is piped (not a TTY), colorama detects the non-TTY stream and strips all ANSI escape codes instead of passing them through.The condition on writer.py line 49 routes through
write_stream_with_colors_win()whenever colors are requested on Windows — even when stdout is piped to a pager. That function writes decoded text through colorama's wrapper, which strips the ANSI codes.The regular
write_stream()path writes raw bytes directly tooutfile.buffer, bypassing colorama's text-layer stripping entirely — so ANSI codes pass through to the pipe intact.Fix
Added
env.stdout_isattyto the condition:write_stream_with_colors_win()is now only used when stdout is an actual terminal. When piped, the standardwrite_stream()path handles output — writing raw bytes with ANSI codes intact, letting pagers likeless -rrender colors correctly.Platform impact
is_windowsisFalse, path never enteredTesting
Verified on Windows 10 with
lessvia Git for Windows:less -r