osrf_pycommon.terminal_color package
Submodules
Module contents
This module provides tools for colorizing terminal output.
This module defines the ansi escape sequences used for colorizing the
output from terminal programs in Linux.
You can access the ansi escape sequences using the ansi()
function:
>>> from osrf_pycommon.terminal_color import ansi
>>> print(["This is ", ansi('red'), "red", ansi('reset'), "."])
['This is ', '\x1b[31m', 'red', '\x1b[0m', '.']
You can also use format_color()
to do in-line substitution of keys
wrapped in @{}
markers for their ansi escape sequences:
>>> from osrf_pycommon.terminal_color import format_color
>>> print(format_color("This is @{bf}blue@{reset}.").split())
['This', 'is', '\x1b[34mblue\x1b[0m.']
This is a list of all of the available substitutions:
Long Form |
Shorter |
Value |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
These substitution’s values come from the ANSI color escape sequences, see: http://en.wikipedia.org/wiki/ANSI_escape_code
Also for any of the keys which have a trailing f
, you can safely drop the
trailing f
and get the same thing.
For example, format_color("@{redf}")
and format_color("@{red}")
are
functionally equivalent.
Also, many of the substitutions have shorten forms for convenience, such that
@{redf}
, @{rf}
, @{red}
, and @{r}
are all the same.
Note that a trailing b
is always required when specifying a background.
Some of the most common non-color sequences have {}
’less versions.
For example, @{boldon}
’s shorter form is @!
.
By default, the substitutions (and calls to ansi()
) resolve to escape
sequences, but if you call disable_ansi_color_substitution_globally()
then they will resolve to empty strings.
This allows you to always use the substitution strings and disable them globally when desired.
On Windows the substitutions are always resolved to empty strings as the
ansi escape sequences do not work on Windows.
Instead strings annotated with @{}
style substitutions or raw \x1b[xxm
style ansi escape sequences must be passed to print_color()
in order
for colors to be displayed on windows.
Also the print_ansi_color_win32()
function can be used on strings
which only contain ansi escape sequences.
Note
There are existing Python modules like
colorama which provide ansi
colorization on multiple platforms, so a valid question is:
“why write this module?”.
The reason for writing this module is to provide the color annotation of
strings and functions for removing or replacing ansi escape sequences which
are not provided by modules like colorama.
This module could have depended on colorama for colorization on Windows,
but colorama works by replacing the built-in sys.stdout
and
sys.stderr
, which we did not want and it has extra functionality that
we do not need.
So, instead of depending on colorama, the Windows color printing code
was used as the inspiration for the Windows color printing in the
windows.py
module in this terminal_color
package.
The colorama license was placed in the header of that file and the colorama
license is compatible with this package’s license.
- osrf_pycommon.terminal_color.ansi(key)
Returns the escape sequence for a given ansi color key.
- osrf_pycommon.terminal_color.disable_ansi_color_substitution_globally()
Causes
format_color()
to replace color annotations with empty strings.It also affects
ansi()
.This is not the case by default, so if you want to make all substitutions given to either function mentioned above return empty strings then call this function.
The default behavior can be restored by calling
enable_ansi_color_substitution_globally()
.
- osrf_pycommon.terminal_color.enable_ansi_color_substitution_globally()
Causes
format_color()
to replace color annotations with ansi esacpe sequences.It also affects
ansi()
.This is the case by default, so there is no need to call this everytime.
If you have previously caused all substitutions to evaluate to an empty string by calling
disable_ansi_color_substitution_globally()
, then you can restore the escape sequences for substitutions by calling this function.
- osrf_pycommon.terminal_color.format_color(msg)
Replaces color annotations with ansi escape sequences.
See this module’s documentation for the list of available substitutions.
If
disable_ansi_color_substitution_globally()
has been called then all color annotations will be replaced by empty strings.Also, on Windows all color annotations will be replaced with empty strings. If you want colorization on Windows, you must pass annotated strings to
print_color()
.- Parameters:
msg (str) – string message to be colorized
- Returns:
colorized string
- Return type:
str
- osrf_pycommon.terminal_color.get_ansi_dict()
Returns a copy of the dictionary of keys and ansi escape sequences.
- osrf_pycommon.terminal_color.print_ansi_color_win32(*args, **kwargs)
Prints color string containing ansi escape sequences to console in Windows.
If called on a non-Windows system, a
NotImplementedError
occurs.Does not respect
disable_ansi_color_substitution_globally()
.Does not substitute color annotations like
@{r}
or@!
, the string must already contain the\033[1m
style ansi escape sequences.Works by splitting each argument up by ansi escape sequence, printing the text between the sequences, and doing the corresponding win32 action for each ansi sequence encountered.
- osrf_pycommon.terminal_color.print_color(*args, **kwargs)
Colorizes and prints with an implicit ansi reset at the end
Calls
format_color()
on each positional argument and then sends all positional and keyword arguments toprint
.If the
end
keyword argument is not present then the default end valueansi('reset') + '\n'
is used and passed toprint
.os.linesep
is used to determine the actual value for\n
.Therefore, if you use the
end
keyword argument be sure to include an ansi reset escape sequence if necessary.On Windows the substituted arguments and keyword arguments are passed to
print_ansi_color_win32()
instead of justprint
.
- osrf_pycommon.terminal_color.remove_ansi_escape_senquences(string)
Removes any ansi escape sequences found in the given string and returns it.
- osrf_pycommon.terminal_color.remove_ansi_escape_sequences(string)
Removes any ansi escape sequences found in the given string and returns it.
- osrf_pycommon.terminal_color.sanitize(msg)
Sanitizes the given string to prevent
format_color()
from substituting content.For example, when the string
'Email: {user}@{org}'
is passed toformat_color()
the@{org}
will be incorrectly recognized as a colorization annotation and it will fail to substitute with aKeyError
:org
.In order to prevent this, you can first “sanitize” the string, add color annotations, and then pass the whole string to
format_color()
.If you give this function the string
'Email: {user}@{org}'
, then it will return'Email: {{user}}@@{{org}}'
. Then if you pass that toformat_color()
it will return'Email: {user}@{org}'
. In this wayformat_color()
is the reverse of this function and so it is safe to call this function on any incoming data if it will eventually be passed toformat_color()
.In addition to expanding
{
=>{{
,}
=>}}
, and@
=>@@
, this function will also replace any instances of@!
,@/
,@_
, and@|
with@{atexclamation}
,@{atfwdslash}
,@{atunderscore}
, and@{atbar}
respectively. And then there are corresponding keys in the ansi dict to convert them back.For example, if you pass the string
'|@ Notice @|'
to this function it will return'|@@ Notice @{atbar}'
. And sinceansi('atbar')
always returns@|
, even whendisable_ansi_color_substitution_globally()
has been called, the result of passing that string toformat_color()
will be'|@ Notice @|'
again.There are two main strategies for constructing strings which use both the Python
str.format()
function and the colorization annotations.One way is to just build each piece and concatenate the result:
print_color("@{r}", "{error}".format(error=error_str)) # Or using print (remember to include an ansi reset) print(format_color("@{r}" + "{error}".format(error=error_str) + "@|"))
Another way is to use this function on the format string, concatenate to the annotations, pass the whole string to
format_color()
, and then format the whole thing:print(format_color("@{r}" + sanitize("{error}") + "@|") .format(error=error_str))
However, the most common use for this function is to sanitize incoming strings which may have unknown content:
def my_func(user_content): print_color("@{y}" + sanitize(user_content))
This function is not intended to be used on strings with color annotations.
- Parameters:
msg (str) – string message to be sanitized
- Returns:
sanitized string
- Return type:
str
- osrf_pycommon.terminal_color.split_by_ansi_escape_sequence(string, include_delimiters=False)
Splits a string into a list using any ansi escape sequence as a delimiter.
- Parameters:
string (str) – string to be split
include_delimiters (bool) – If True include matched escape sequences in the list (default: False)
- Returns:
list of strings, split from original string by escape sequences
- Return type:
list
- osrf_pycommon.terminal_color.test_colors(file=None)
Prints a color testing block using
print_color()