The illegibility of python tracebacks has bugged me for a while, so I finally got around to adding color to my terminal (bash) output.
Basically, the “lightest” way I found is to redirect the python stdout output through a sed script that injects some color codes before spitting the output back to your terminal (and then to your eyes).
My system is Ubuntu 18.04, in bash. Not sure how it’d translate over to Mac or Windows — it relies on these annoying color escape codes. (according to internet, should work on OSX and Windows terminals)
How
Add to your ~/.bashrc
:
norm="$(printf '\033[0m')" #returns to "normal" bold="$(printf '\033[0;1m')" #set bold red="$(printf '\033[0;31m')" #set red boldyellowonblue="$(printf '\033[0;1;33;44m')" boldyellow="$(printf '\033[0;1;33m')" boldred="$(printf '\033[0;1;31m')" #set bold, and set red. copython() { python $@ 2>&1 | sed -e "s/Traceback/${boldyellowonblue}&${norm}/g" \ -e "s/File \".*\.py\".*$/${boldyellow}&${norm}/g" \ -e "s/\, line [[:digit:]]\+/${boldred}&${norm}/g" }
Then to use it, run
$ source ~/.bashrc # reload file without restarting terminal $ copython myprogram.py # copython = colored python
Originally, the program outputs:
With `copython`
it now outputs
Based on:
https://stackoverflow.com/questions/20909942/color-linux-command-output/20910449#20910449
Mostly, I just tacked on more sed
regex’s, and changed the colors around a bit.
The result is actually kinda inverted from a UX standpoint — probably want the actual code highlighted more than the file / line number — but we’re reaching the limits of my patience with regex’s here.
This is fairly lightweight but definitely still tacks on some time! (My regex’s are not very efficient I’m sure). Fortunately easy to switch between `copython` and `python` if concerned 🙂
Explanation: ANSI Color Codes
Note that \033[
marks the beginning of a code, which helped me understand a bit better what is going on.
0m # normal 0;1m # bold 0;1;33;44m # bold yellow on blue 0;1;33m # bold yellow 0;1;31m # bold red
So I guess the first 1
indicates bold, then the second 33
indicates foreground color, and the third 44
indicates background color. Something like that.
I think there’s eight main possible colors, going from 30 to 37 for foreground, and 40 to 47 for background colors.
# Foreground Regular Colors 30m' # Black 31m' # Red 32m' # Green 33m' # Yellow 34m' # Blue 35m' # Purple 36m' # Cyan 37m' # White # Background Regular Colors 40m' # Black 41m' # Red 42m' # Green 43m' # Yellow 44m' # Blue 45m' # Purple 46m' # Cyan 47m' # White
Alternatives: Vimcat
Pipe it through vim! Specifically my step-by-step answer is at the bottom. Unfortunately, this both (a) requires installing things and (b) is slow. See before and after in this image:
CON: It’s noticeably slow.
Alternatives: IPython
import sys from IPython.core import ultratb sys.excepthook = ultratb.FormattedTB(mode='Verbose', color_scheme='Linux', call_pdb=False)
CON: Have to edit every single python file! Also incredibly slow.
[END]
Notes to self
next post todo: cover coloring output of python logger.py module
https://stackoverflow.com/questions/384076/how-can-i-color-python-logging-output
specifically this Â
sneak preview:
I still don’t fully understand the nesting of loggers — you can see ‘white’ output from some other logger being called by the main file. (also a few print() messages I haven’t converted yet).
linkback to hexblog draft of this post