Repair colorama wrapping on non-Windows platforms (#1670)

* Repair colorama wrapping on non-Windows platforms

The wrap_stream_for_windows() function calls
colorama.initialise.wrap_stream() function to apply colorama's magic to
wrapper to the output stream. Except this wrapper is only applied on
Windows platforms that need it, otherwise the original stream is
returned as-is.

The colorama wrapped stream lacks a detach() method, so a no-op lambda
was being assigned to the wrapped stream.

The problem is that the no-op lambda was being assigned unconditionally
whether or not colorama actually returns a wrapped stream, thus
replacing the original TextIOWrapper's detach() method. Replacing the
detach() method with a no-op lambda is the root cause of the problem
observed in #1664.

The solution is to only assign the no-op detach() method if the stream
lacks its own detach() method.

Repairs #1664
This commit is contained in:
Pete Grayson 2020-09-27 21:41:11 +00:00 committed by GitHub
parent bc138d1263
commit 4d71d74a44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 19 deletions

View File

@ -15,6 +15,8 @@
- fixed a crash when PWD=/ on POSIX (#1631)
- fixed "I/O operation on closed file" when using --diff (#1664)
- Prevent coloured diff output being interleaved with multiple files (#1673)
- Added support for PEP 614 relaxed decorator syntax on python 3.9 (#1711)

View File

@ -636,6 +636,7 @@ Multiple contributions by:
- [Paul Ganssle](mailto:p.ganssle@gmail.com)
- [Paul Meinhardt](mailto:mnhrdt@gmail.com)
- [Peter Bengtsson](mailto:mail@peterbe.com)
- [Peter Grayson](mailto:pete@jpgrayson.net)
- [Peter Stensmyr](mailto:peter.stensmyr@gmail.com)
- pmacosta
- [Quentin Pradet](mailto:quentin@pradet.me)

View File

@ -871,30 +871,22 @@ def color_diff(contents: str) -> str:
def wrap_stream_for_windows(
f: io.TextIOWrapper,
) -> Union[io.TextIOWrapper, "colorama.AnsiToWin32.AnsiToWin32"]:
) -> Union[io.TextIOWrapper, "colorama.AnsiToWin32"]:
"""
Wrap the stream in colorama's wrap_stream so colors are shown on Windows.
Wrap stream with colorama's wrap_stream so colors are shown on Windows.
If `colorama` is not found, then no change is made. If `colorama` does
exist, then it handles the logic to determine whether or not to change
things.
If `colorama` is unavailable, the original stream is returned unmodified.
Otherwise, the `wrap_stream()` function determines whether the stream needs
to be wrapped for a Windows environment and will accordingly either return
an `AnsiToWin32` wrapper or the original stream.
"""
try:
from colorama import initialise
# We set `strip=False` so that we can don't have to modify
# test_express_diff_with_color.
f = initialise.wrap_stream(
f, convert=None, strip=False, autoreset=False, wrap=True
)
# wrap_stream returns a `colorama.AnsiToWin32.AnsiToWin32` object
# which does not have a `detach()` method. So we fake one.
f.detach = lambda *args, **kwargs: None # type: ignore
from colorama.initialise import wrap_stream
except ImportError:
pass
return f
return f
else:
# Set `strip=False` to avoid needing to modify test_express_diff_with_color.
return wrap_stream(f, convert=None, strip=False, autoreset=False, wrap=True)
def format_stdin_to_stdout(