How to use the new support for ANSI escape sequences in the Windows 10 console?

Use the solution suggested here: https://stackoverflow.com/a/293633/18487576

Run:

os.system('color')

to enable color mode on the terminal.

I was using the accepted answer with ctypes until I discovered this. This solution does not require any additional installations or native API chicanery.

This command is not an executable file, but a specific command within the Windows cmd terminal.

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/color

Its official use is to change foreground/background colors of the shell. The fact that it will activate ANSI/VT100 is apparently undocumented.


The problem is that the Python interpreter doesn't enable the processing of ANSI escape sequences. The ANSI sequences work from the Windows command prompt because cmd does enable them. If you start Python from the command prompt you'll find the ANSI sequences do work, including the ones for enabling and disabling the cursor. That's because cmd has already enabled them for that console window.

If you want have something you can click on to start the Python interpreter with ANSI escapes enabled you can create a shortcut that runs a command something like cmd /c C:\PythonXY\python.

Another, harder, solution would be to use ctypes to enable ANSI escape sequence processing for the console window by calling the SetConsoleMode Windows API with the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag set. For example:

import ctypes

kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)

The colorama package enables ANSI codes in Windows.

Usage:

from colorama import init
init()

After that ANSI codes should work.


This adaptation of some code I proposed here should help get you started. Enables ANSI VT mode (virtual terminal processing) on Windows 10. Pass in argument value 1 for stdout or 2 stderr.

def _windows_enable_ANSI(std_id):
    """Enable Windows 10 cmd.exe ANSI VT Virtual Terminal Processing."""
    from ctypes import byref, POINTER, windll, WINFUNCTYPE
    from ctypes.wintypes import BOOL, DWORD, HANDLE

    GetStdHandle = WINFUNCTYPE(
        HANDLE,
        DWORD)(('GetStdHandle', windll.kernel32))

    GetFileType = WINFUNCTYPE(
        DWORD,
        HANDLE)(('GetFileType', windll.kernel32))

    GetConsoleMode = WINFUNCTYPE(
        BOOL,
        HANDLE,
        POINTER(DWORD))(('GetConsoleMode', windll.kernel32))

    SetConsoleMode = WINFUNCTYPE(
        BOOL,
        HANDLE,
        DWORD)(('SetConsoleMode', windll.kernel32))

    if std_id == 1:       # stdout
        h = GetStdHandle(-11)
    elif std_id == 2:     # stderr
        h = GetStdHandle(-12)
    else:
        return False

    if h is None or h == HANDLE(-1):
        return False

    FILE_TYPE_CHAR = 0x0002
    if (GetFileType(h) & 3) != FILE_TYPE_CHAR:
        return False

    mode = DWORD()
    if not GetConsoleMode(h, byref(mode)):
        return False

    ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
    if (mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0:
        SetConsoleMode(h, mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
    return True