3

I'm looking for a way to reliably test if the output (stdout, stderr) terminal is ANSI (or any) color capable.

Because most terminals today, even on Windows, does support at least ANSI colors, all the answers I have found, are either outdated or wrong. (I already know how easy it is to print color test patterns and check for Unicode/UTF-8 capability.)

I have seen partial tries and variations of this:

It should be noted that this is quite easy to do for a *nix based environment, as they almost always have the TERM variable set to an xterm-type. But was hoping to also find some Windows environment variable for this.

Q: How can I have my python3 code to check if the output is using a color capable terminal/console?

The answer need to be cross-platform compatible, being able to check this on windows, for example.


UPDATE:

Apparently this is not an easy problem! It seem to depend on many factors, like:

  • What is your Windows OS version
  • What is your PowersHell version
  • What is your "terminal/console" capabilities? (poweshell, mintty, cmd are all very diiferent)
  • What are the fonts used in those "consoles"?
  • What character sets are you using? (ASCII, UTF-8/16, etc.)
not2qubit
  • 14,531
  • 8
  • 95
  • 135
  • If Windows is the only odd one out, test `os.name`. – Jongware Dec 02 '18 at 10:59
  • 1
    POSIX systems should support the [curses module](https://docs.python.org/3/library/curses.html), e.g. `curses.setupterm();` `is_color_terminal = curses.tigetnum('colors') > 0`. – Eryk Sun Dec 02 '18 at 16:03
  • For Windows you'll need ctypes. For example: `ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4;` `kernel32 = ctypes.WinDLL('kernel32', use_last_error=True);` `hstdout = msvcrt.get_osfhandle(sys.stdout.fileno());` `mode = ctypes.c_ulong();` `is_color_terminal = kernel32.GetConsoleMode(hstdout, ctypes.byref(mode)) and (mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0)`. Then if it's not enabled, try enabling it: `is_color_terminal = kernel32.SetConsoleMode(hstdout, mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) > 0`. – Eryk Sun Dec 02 '18 at 16:19
  • Funny, I was just commenting on an old [post](https://stackoverflow.com/questions/44047988/windows-10-console-colors-not-working-virtual-terminal-control-character-sequen) of yours at the same time...:) – not2qubit Dec 02 '18 at 16:44
  • So is the Windows `CMD`, `PS` or `"console"`, supporting POSIX? It seem (from the link above, to the other thread), that there can be very mixed results. – not2qubit Dec 02 '18 at 16:55
  • 1
    cmd.exe and python.exe are Windows console applications, which means they automatically inherit the parent's console or allocate a new console if the parent doesn't have one. In contrast, graphical applications have to manually attach to or allocate a console. The console is hosted in another process, and clients communicate with it via standard I/O and the console API. In Windows 7+ each console is hosted by a separate instance of conhost.exe. – Eryk Sun Dec 02 '18 at 18:33
  • In Windows 10, conhost.exe defaults to an enhanced version with virtual terminal support, but VT mode is disabled by default. Applications that need VT support should enable it via `GetConsoleMode` and `SetConsoleMode`, as shown above. A user can also enable it by default by setting a DWORD value of 1 named "VirtualTerminalLevel" in the registry key "HKCU\Console". – Eryk Sun Dec 02 '18 at 18:38
  • @eryksun I tried to run the above with PS, but it didn't work. Perhaps it's not PS? Anyway, for this topic your first answer seem to work AFAICT. But please post and answer so that I can accept it. – not2qubit Dec 06 '18 at 21:52
  • Ok I got that code converted into Cygwin ctypes, which means that it doesn't use the python Window'isms, of `WinDLL` and `wintypes`. However, the writing fails. What is interesting is that you use the `OSF` handle for the reading and writing. [What is the difference?](https://stackoverflow.com/questions/53775994/how-to-get-a-handle-on-windows-stdout-handles-in-python) – not2qubit Dec 14 '18 at 17:28
  • re: `is Windows odd one out` Even here it is more complicated. `git-bash` on Windows , `cmd` and `PowerShell` : all are capable of color, yet python _thinks_ they are not capable of color by most offered tests. I presume it is because they are all effectively a hosted stdin/stdout/stderr set. – Jesse Chisholm Feb 18 '22 at 21:15

0 Answers0