Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Color is not outputted on Git Bash #988

Closed
musse opened this issue Feb 5, 2021 · 6 comments
Closed

[BUG] Color is not outputted on Git Bash #988

musse opened this issue Feb 5, 2021 · 6 comments

Comments

@musse
Copy link

musse commented Feb 5, 2021

Describe the bug
When running a Python script using Rich with Git Bash on Windows, color is not outputted.

To Reproduce
Simply run the following code on a Git Bash terminal:

import rich

rich.print('[red]This text should be red[/red]')

Forcing terminal and/or disabling legacy Windows mode do not work either:

import rich.console

console = rich.console.Console(force_terminal=True, legacy_windows=False)
console.print('[red]This text should be red[/red]')

Platform
Windows 10, Git Bash (MINGW64)

Diagnose

$ python -m rich.diagnose
+---------------------- <class 'rich.console.Console'> -----------------------+
| A high level console interface.                                             |
|                                                                             |
| +-------------------------------------------------------------------------+ |
| | <console width=79 None>                                                 | |
| +-------------------------------------------------------------------------+ |
|                                                                             |
|     color_system = None                                                     |
|         encoding = 'cp1252'                                                 |
|             file = <colorama.ansitowin32.StreamWrapper object at            |
|                    0x0203EC88>                                              |
| is_dumb_terminal = False                                                    |
|       is_jupyter = False                                                    |
|      is_terminal = False                                                    |
|   legacy_windows = True                                                     |
|         no_color = False                                                    |
|          options = ConsoleOptions(legacy_windows=True, min_width=1,         |
|                    max_width=79, is_terminal=False, encoding='cp1252',      |
|                    justify=None, overflow=None, no_wrap=False,              |
|                    highlight=None)                                          |
|           record = False                                                    |
|         safe_box = True                                                     |
|             size = ConsoleDimensions(width=79, height=24)                   |
|        soft_wrap = False                                                    |
|           stderr = False                                                    |
|            style = None                                                     |
|         tab_size = 8                                                        |
|            width = 79                                                       |
+-----------------------------------------------------------------------------+

$ python -m rich._windows
platform="Windows"
WindowsConsoleFeatures(vt=False, truecolor=False)

$ pip freeze | grep rich
rich==9.10.0

Additional info

I've investigated the Rich coding and the problematic code seem to be related to the colorama.init() call.

If I comment out the call to colorama.init() and set force_terminal to True, then I get color on the output. Git Bash emulates BASH on Windows, so I assume it is expecting ANSI codes. However, detect_legacy_windows() is incorrectly returning True; therefore, colorama.init() is called and ANSI codes are not outputted.

I think the fix would be to make detect_legacy_windows() return False when running on Git Bash/MINGW, but I'm not sure how to do it.

@musse
Copy link
Author

musse commented Feb 5, 2021

Relevant issue: tartley/colorama#224

It seems there is a PR on Colorama that would fix the issue, but it has not been merged yet: tartley/colorama#226

@willmcgugan
Copy link
Collaborator

Thanks for doing the research there. Detecting terminal capabilities on Windows is messy. I think that detecting the TERM env var may be enough to disable the legacy_windows check. I'll give it some thought. I'd also accept a PR if you want to tackle it.

@musse
Copy link
Author

musse commented Feb 5, 2021

I can give it a try. Do you think it makes sense to handle the colorama.init() on the Console class depending on the value of legacy_windows? Doing so would allow to easily disable the colorama call by forcing legacy_windows to False. We could use colorama's deinit() and reinit() to handle this logic per-Console.

@musse
Copy link
Author

musse commented Feb 5, 2021

Additional context: I'm trying to create a Git pre-commit hook to run a Python script that uses Rich for colored output. When running the pre-commit hook on Linux, everything works fine. When running on Windows, I don't get any colors on any Terminal (Windows Terminal, regular cmd, Git Bash). If I run the Python script directly, I do get colors on Windows Terminal and cmd, but not on Git Bash. I was able to get colors when running the script directly on Git Bash by setting PYCHARM_HOSTED=1 (like described on tartley/colorama#224), but I still don't get colors when running it through pre-commit hook on all terminals I've tried. The only way I've managed to get colors with the pre-commit hook is disabling the colorama.init() call.

@willmcgugan
Copy link
Collaborator

I think the reason you don't get colors in some environments, is that Colorama strips all ANSI codes if it thinks that it is not writing to a terminal.

We could use colorama's deinit() and reinit() to handle this logic per-Console. We could use colorama's deinit() and reinit() to handle this logic per-Console.

That might work. The problem is that it has global effect. An app could have several Console instances with different settings, writing in different threads. The ideal solution would be to isolate the Colorama magic to a single Console instance. I briefly tackled that, but didn't manage to make it work.

So I'm not sure what the best solution is. If you were to make any changes, it would have to not break Windows terminal and cmd.exe. Good luck!

@willmcgugan
Copy link
Collaborator

I don’t think there is a great solution to this that doesn’t require reimplementing colorama. Closing for now, but I suspect I will revisit it in future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants