ignoring_gravity
ignoring_gravity

Reputation: 10531

Capture color when running subprocess.run

If I do:

$ mkdir foo
$ touch foo/__init__.py

And then run

$ mypy foo             
Success: no issues found in 1 source file

then "Success: no issues found in 1 source file" is coloured green.

However, if I make a file t.py with

import subprocess

output = subprocess.run(['mypy', 'foo'], text=True, capture_output=True)
print(output)

and run it:

$ python t.py
CompletedProcess(args=['mypy', 'foo'], returncode=0, stdout='Success: no issues found in 1 source file\n', stderr='')

then stdout only contains the message - the color is gone, and so is any hope of reconstructing it.

So, how could I run mypy foo from within t.py in such a way that I can get the color from stdout?

Upvotes: 0

Views: 941

Answers (1)

xorover
xorover

Reputation: 139

TL;DR

import subprocess, os
my_env = os.environ.copy()
my_env['MYPY_FORCE_COLOR'] = '1'

output = subprocess.run(['mypy', 'foo'], text=True, capture_output=True, env=my_env);
print(output.stdout)

First, it's normal that most of the console programs output data without colors if they think they haven't been run in interactive mode.
So, we need to force it to do so.

There is an undocumented environment variable MYPY_FORCE_COLOR that will force color. (source)

Till now, mypy doesn't have a documented command line option to do so, but we can use this hack. Beware that this behavior may change some day!

Code:

# ...
import os
my_env = os.environ.copy()
my_env['MYPY_FORCE_COLOR'] = '1'

# Set modified env
subprocess.run(..., env=my_env);
# ...

Then, print actual stdout to see ANSI escape codes (that is, colors).

print(output.stdout)

Upvotes: 2

Related Questions