39

If I run this in python under linux it works:

start = "\033[1;31m"
end = "\033[0;0m"
print "File is: " + start + "<placeholder>" + end

But if I run it in Windows it doesn't work, how can I make the ANSI escape codes work also on Windows?

Neuron
  • 5,141
  • 5
  • 38
  • 59
Eduard Florinescu
  • 16,747
  • 28
  • 113
  • 179
  • 2
    see http://stackoverflow.com/questions/8358533/python-module-to-enable-ansi-for-stdout-on-windows if could be useful – pr0gg3d Sep 19 '12 at 10:36
  • Why are you using '\033' when '\33' is the same thing? – Apostolos Sep 22 '20 at 05:37
  • 1
    @Apostolos they are the same but I use '\033' from habit due to bash. also \0 and starting with 0 is explicit for octal in many languages, being descriptive there can be no confusion – Eduard Florinescu Sep 22 '20 at 10:40

11 Answers11

44

For windows, calling os.system("") makes the ANSI escape sequence get processed correctly:

import os
os.system("")  # enables ansi escape characters in terminal

COLOR = {
    "HEADER": "\033[95m",
    "BLUE": "\033[94m",
    "GREEN": "\033[92m",
    "RED": "\033[91m",
    "ENDC": "\033[0m",
}

print(COLOR["GREEN"], "Testing Green!!", COLOR["ENDC"])
Neuron
  • 5,141
  • 5
  • 38
  • 59
Gary Vernon Grubb
  • 9,695
  • 1
  • 24
  • 27
  • 3
    nice answer since it doens't need new modules to be installed – Eduard Florinescu Oct 06 '20 at 09:39
  • 9
    You don't need to call color. Command prompt supports color by default so you can just do `os.system("")` (At least for me) – YJiqdAdwTifMxGR Jan 05 '21 at 17:11
  • Thanks for the info, I just tested and it works for me as well. – Gary Vernon Grubb Jan 06 '21 at 03:57
  • 7
    `os.system("color")` is more explicit than `os.system("")`. Think, how little someone reading the code can anticipate from the latter. – Wör Du Schnaffzig Jul 22 '21 at 07:36
  • @avans Gary's solution of just using `os.system()` may be less descriptive, but it may improve cross-compatibility as different terminals may interpret the command `color` differently, because `os.system` is known for displaying output. Maybe just use a comment instead? – Anony Mous Jul 19 '22 at 09:43
  • Somewhere underneath the hood, this is causing the console mode to change to 7 like @Ubuesque answer does directly. – Andy Nov 15 '22 at 20:59
25

Here is the solution I have long sought. Simply use the ctypes module, from the standard library. It is installed by default with Python 3.x, only on Windows. So check if the OS is Windows before to use it (with platform.system, for example).

import os
if os.name == 'nt': # Only if we are running on Windows
    from ctypes import windll
    k = windll.kernel32
    k.SetConsoleMode(k.GetStdHandle(-11), 7)

After you have done that, you can use ASCII special characters (like \x1b[31m, for red color) as if you were on a Unix operating system :

message = "ERROR"
print(f"\x1b[31m{message}\x1b[0m")

I like this solution because it does not need to install a module (like colorama or termcolor).

Ubuesque
  • 351
  • 5
  • 7
  • 1
    Exactly! This is the right, efficient way in which a programmer should think! (It's amazing the number of persons using extra packages to solve a problem when it can be solved with built-in modules!) – Apostolos Sep 22 '20 at 05:50
  • 1
    thanks sir, this is exactly the solution what I was looking for, here, have a upvote – NoahVerner Sep 07 '21 at 13:52
  • 1
    this must be answer – Maxim Akristiniy Oct 27 '21 at 19:10
  • On Windows 11: Works great in Git for Windows Console, Command Prompt's default Console Host, and Microsoft's new "Windows Terminal". However if you accidentally put Console Host in "[Legacy mode](https://learn.microsoft.com/en-us/windows/console/legacymode)" like I did, then you will discover this does not work (it is unable to change the Console Mode). In that small case, `colorama`'s magic is still needed. – Andy Nov 15 '22 at 20:52
21

You could check Python module to enable ANSI colors for stdout on Windows? to see if it's useful.

The colorama module seems to be cross-platform.

You install colorama:

pip install colorama

Then:

import colorama
colorama.init()
start = "\033[1;31m"
end = "\033[0;0m"
print "File is: " + start + "<placeholder>" + end
Community
  • 1
  • 1
pr0gg3d
  • 977
  • 5
  • 7
9

If you are on Win 10 (with native ANSI support in cmd) there seems to be a bug which was marked as resolved in Python 3.7 (though it doesn't look it was actually fixed).

One workaround is to add subprocess.call('', shell=True) before printing.

Dan M.
  • 3,818
  • 1
  • 23
  • 41
3

You could take a look at https://github.com/kennethreitz/clint

From the readme:

>>> from clint.textui import colored, puts

>>> puts(colored.red('red text'))
red text

# It's red in Windows, OSX, and Linux alike.
mfussenegger
  • 3,931
  • 23
  • 18
  • If I would use something I'd like something that comes with the standard library. – Eduard Florinescu Sep 19 '12 at 10:42
  • 4
    You could still take a look at the source. Behind the curtains it uses colarama, which basically wraps sys.stdout.write to replace the escape sequences. – mfussenegger Sep 19 '12 at 10:48
  • Installing special module when something can be done with standard libraries ... Bad solution! – Apostolos Sep 20 '20 at 17:30
  • @Apostolos on the contrary! modules exist for a reason. There are often many pit falls which will lead to your code not working on some systems. by using well tested and used code you get a much higher certainty of your code working. A good softwaredev should not reinvent the wheel for every project – Neuron Jan 17 '22 at 19:05
  • I don't know about pitfalls ... I can't remember any case that a built-in module has not worked as it should, but there might be. And in case a built-in module doesn't work as you want, **then only** you can look for an external module as substitute, This is what simple logic says. – Apostolos Jan 19 '22 at 19:01
3

You can just do this:

import os
os.system("")

This works for me. Command prompt does support color by default.

YJiqdAdwTifMxGR
  • 123
  • 1
  • 11
  • Thanks! For others: I just added that code to the top of my python file and I was able to use those ANSI or ESC codes in windows. – Wavesailor Feb 03 '21 at 23:21
2

Sending the ANSI escape sequences should work, according to thousands of fine answers on the internet, but one obscure detail took me two half days to stumble upon. The trick is that a certain registry key must be set. I'm using (just for today) Windows 10 Enterprise, version 1709, build 16299.

In HKEY_CURRENT_USER, under Console, right between TrimLeadingZeros and WindowAlpha there should be VirtualTerminalLevel. If it doesn't exist, go ahead and create it. It's a REG_DWORD. Set its value to 1. Open a new terminal, run Python, and have a bit o' fun.

print("\033[48;2;255;140;60m ORANGE BACKGROUND \033[48;2;0;0;0m")

See https://github.com/ytdl-org/youtube-dl/issues/15758 to read stuff by people who know more than I do about this.

Now if I could remember why I wanted to colorize my Python program's output...

DarenW
  • 16,549
  • 7
  • 63
  • 102
2

Here is a bit simpler code I have used.

import os
os.system("color") # Alternative - os.system("")

TCOLOR = "\033[31;3m"
ENDC = "\033[m"
print (TCOLOR + "Make yourself happy" + ENDC)
1

I wrote a simple module, available at: http://pypi.python.org/pypi/colorconsole

It works with Windows, Mac OS X and Linux. It uses ANSI for Linux and Mac, but native calls to console functions on Windows. You have colors, cursor positioning and keyboard input. It is not a replacement for curses, but can be very useful if you need to use in simple scripts or ASCII games.

The docs can be found here: http://code.google.com/p/colorconsole/wiki/PageName

PS: This is the same answer for Print in terminal with colors using Python?, but I didn't know how to link to a reply.

Community
  • 1
  • 1
nmenezes
  • 910
  • 6
  • 12
1

Try adding a semi-colon here \033[;, I get undesirable effects without that semi-colon.

start = "\033[;1;31m"
end = "\033[;0;0m"
0
import os
os.system("")

COR = {
    "HEADER": "\033[95m",
    "BLUE": "\033[94m",
    "GREEN": "\033[92m",
    "RED": "\033[91m",
    "ENDC": "\033[0m",
}

print(COR["RED"]+"Testing Green!!"+COR["ENDC"])