spack.llnl.util.tty package¶
- class spack.llnl.util.tty.SuppressOutput(msg_enabled: bool = True, warn_enabled: bool = True, error_enabled: bool = True)[source]¶
Bases:
objectClass for disabling output in a scope using
withkeyword
- spack.llnl.util.tty.debug(message, *args, level: int = 1, format: str = 'g', stream: IO[str] | None = None, **kwargs) None[source]¶
Print a debug message if the debug level is set.
- spack.llnl.util.tty.error(message, *args, format: str = '*r', stream: IO[str] | None = None, **kwargs) None[source]¶
Print an error message.
- spack.llnl.util.tty.hline(label: str | None = None, *, char: str = '-', max_width: int = 64) None[source]¶
Draw a labeled horizontal line.
- Parameters:
char – char to draw the line with
max_width – maximum width of the line
- spack.llnl.util.tty.info(message: Exception | str, *args, format: str = '*b', stream: IO[str] | None = None, wrap: bool = False, break_long_words: bool = False, countback: int = 3) None[source]¶
Print an informational message.
- spack.llnl.util.tty.msg(message: Exception | str, *args: str, newline: bool = True) None[source]¶
Print a message to the console.
- spack.llnl.util.tty.output_filter(filter_fn: Callable[[str], str]) Iterator[None][source]¶
Context manager that applies a filter to all output.
- spack.llnl.util.tty.process_stacktrace(countback: int) str[source]¶
Gives file and line frame
countbackframes from the bottom
- spack.llnl.util.tty.verbose(message, *args, format: str = 'c', **kwargs) None[source]¶
Print a verbose message if the verbose flag is set.
- spack.llnl.util.tty.warn(message, *args, format: str = '*Y', stream: IO[str] | None = None, **kwargs) None[source]¶
Print a warning message.
Submodules¶
spack.llnl.util.tty.colify module¶
Routines for printing columnar output. See colify() for more information.
- spack.llnl.util.tty.colify.colified(elts: List[Any], *, cols: int = 0, indent: int = 0, padding: int = 2, tty: bool | None = None, method: str = 'variable', console_cols: int | None = None)[source]¶
Invokes the
colify()function but returns the result as a string instead of writing it to an output string.
- spack.llnl.util.tty.colify.colify(elts: List[Any], *, cols: int = 0, output: IO | None = None, indent: int = 0, padding: int = 2, tty: bool | None = None, method: str = 'variable', console_cols: int | None = None)[source]¶
Takes a list of elements as input and finds a good columnization of them, similar to how gnu ls does. This supports both uniform-width and variable-width (tighter) columns.
If elts is not a list of strings, each element is first converted using
str.- Keyword Arguments:
output – A file object to write to. Default is
sys.stdoutindent – Optionally indent all columns by some number of spaces
padding – Spaces between columns. Default is 2
width – Width of the output. Default is 80 if tty not detected
cols – Force number of columns. Default is to size to terminal, or single-column if no tty
tty – Whether to attempt to write to a tty. Default is to autodetect a tty. Set to False to force single-column output
method – Method to use to fit columns. Options are variable or uniform. Variable-width columns are tighter, uniform columns are all the same width and fit less data on the screen
console_cols – number of columns on this console (default: autodetect)
- spack.llnl.util.tty.colify.colify_table(table: List[List[Any]], *, output: IO | None = None, indent: int = 0, padding: int = 2, console_cols: int | None = None)[source]¶
Version of
colify()for data expressed in rows, (list of lists).Same as regular colify but:
This takes a list of lists, where each sub-list must be the same length, and each is interpreted as a row in a table. Regular colify displays a sequential list of values in columns.
Regular colify will always print with 1 column when the output is not a tty. This will always print with same dimensions of the table argument.
- spack.llnl.util.tty.colify.config_uniform_cols(elts: List[str], console_width: int, padding: int, cols: int = 0) ColumnConfig[source]¶
Uniform-width column fitting algorithm.
Determines the longest element in the list, and determines how many columns of that width will fit on screen. Returns a corresponding column config.
- spack.llnl.util.tty.colify.config_variable_cols(elts: List[str], console_width: int, padding: int, cols: int = 0) ColumnConfig[source]¶
Variable-width column fitting algorithm.
This function determines the most columns that can fit in the screen width. Unlike uniform fitting, where all columns take the width of the longest element in the list, each column takes the width of its own longest element. This packs elements more efficiently on screen.
If cols is nonzero, force the table to use that many columns and just add minimal padding between the columns.
spack.llnl.util.tty.color module¶
This file implements an expression syntax, similar to printf, for adding
ANSI colors to text.
See colorize(), cwrite(), and cprint() for routines that can
generate colored output.
colorize() will take a string and replace all color expressions with
ANSI control codes. If the isatty keyword arg is set to False, then
the color expressions will be converted to null strings, and the
returned string will have no color.
cwrite() and cprint() are equivalent to write() and print()
calls in python, but they colorize their output. If the stream argument is
not supplied, they write to sys.stdout.
Here are some example color expressions:
Expression |
Meaning |
|---|---|
|
Turn on red coloring |
|
Turn on bright red coloring |
|
Bold foo, but don’t change text color |
|
Underline bar, but don’t change text color |
|
Turn on bold, blue text |
|
Turn on bright blue text with an underline |
|
Revert to plain formatting |
|
Print out ‘green’ in bold, green text, then reset to plain. |
|
Print out ‘green’ in bold, green text, then reset to plain. |
The syntax consists of:
color-expr |
|
style |
|
color-code |
|
text |
|
@ indicates the start of a color expression. It can be followed
by an optional * or _ that indicates whether the font should be bold or
underlined. If * or _ is not provided, the text will be plain. Then
an optional color code is supplied. This can be [krgybmcw] or [KRGYBMCW],
where the letters map to black(k), red(r), green(g), yellow(y), blue(b),
magenta(m), cyan(c), and white(w). Lowercase letters denote normal ANSI
colors and capital letters denote bright ANSI colors.
Finally, the color expression can be followed by text enclosed in {}. If
braces are present, only the text in braces is colored. If the braces are
NOT present, then just the control codes to enable the color will be output.
The console can be reset later to plain text with @..
To output an @, use @@. To output a } inside braces, use }}.
- spack.llnl.util.tty.color.ANSI_CODE_RE¶
matches a standard ANSI color code
- class spack.llnl.util.tty.color.ColorMapping(color, colors, offsets)[source]¶
Bases:
NamedTuple
- exception spack.llnl.util.tty.color.ColorParseError(message: str)[source]¶
Bases:
ExceptionRaised when a color format fails to parse.
- class spack.llnl.util.tty.color.ColorStream(stream: IOBase, color: bool | None = None)[source]¶
Bases:
object
- spack.llnl.util.tty.color.cescape(string: str) str[source]¶
Escapes special characters needed for color codes.
Replaces the following symbols with their equivalent literal forms:
@@@}}}
- spack.llnl.util.tty.color.cextra(string: str) int[source]¶
Length of extra color characters in a string
- spack.llnl.util.tty.color.clen(string: str) int[source]¶
Return the length of a string, excluding ansi color sequences.
- spack.llnl.util.tty.color.cmapping(string: str) ColorMapping[source]¶
Return a mapping for translating indices in a plain string to indices in colored text.
The returned dictionary maps indices in the plain string to the offset of the corresponding indices in the colored string.
- spack.llnl.util.tty.color.color_when(value: str | bool | None) Iterator[None][source]¶
Context manager to temporarily use a particular color setting.
- spack.llnl.util.tty.color.colorize(string: str, color: bool | None = None, enclose: bool = False, zsh: bool = False) str[source]¶
Replace all color expressions in a string with ANSI control codes.
- Parameters:
string – The string to replace
color – If False, output will be plain text without control codes, for output to non-console devices (default: automatically choose color or not)
enclose – If True, enclose ansi color sequences with square brackets to prevent misestimation of terminal width.
zsh – If True, use zsh ansi codes instead of bash ones (for variables like PS1)
- spack.llnl.util.tty.color.cprint(string: str, stream: IO[str] | None = None, color: bool | None = None) None[source]¶
Same as cwrite, but writes a trailing newline to the stream.
- spack.llnl.util.tty.color.csub(string: str) str[source]¶
Return the string with ANSI color sequences removed.
- spack.llnl.util.tty.color.cwrap(string: str, *, initial_indent: str = '', subsequent_indent: str = '', **kwargs) List[str][source]¶
Wrapper around
textwrap.wrap()that handles ANSI color codes.
- spack.llnl.util.tty.color.cwrite(string: str, stream: IO[str] | None = None, color: bool | None = None) None[source]¶
Replace all color expressions in string with ANSI control codes and write the result to the stream. If color is False, this will write plain text with no color. If True, then it will always write colored output. If not supplied, then it will be set based on stream.isatty().
- spack.llnl.util.tty.color.get_color_when(stdout=None) bool[source]¶
Return whether commands should print color or not.
- spack.llnl.util.tty.color.set_color_when(when: str | bool | None) None[source]¶
Set when color should be applied. Options are:
True or
"always": always print colorFalse or
"never": never print colorNone or
"auto": only print color if sys.stdout is a tty.
- spack.llnl.util.tty.color.try_enable_terminal_color_on_windows() None[source]¶
Turns coloring in Windows terminal by enabling VTP in Windows consoles (CMD/PWSH/CONHOST) Method based on the link below https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#example-of-enabling-virtual-terminal-processing
Note: No-op on non windows platforms
spack.llnl.util.tty.log module¶
Utility classes for logging the output of blocks of code.
- class spack.llnl.util.tty.log.StreamWrapper(sys_attr)[source]¶
Bases:
objectWrapper class to handle redirection of io streams
- class spack.llnl.util.tty.log.Unbuffered(stream)[source]¶
Bases:
objectWrapper for Python streams that forces them to be unbuffered.
This is implemented by forcing a flush after each write.
- spack.llnl.util.tty.log.ignore_signal(signum)[source]¶
Context manager to temporarily ignore a signal.
- class spack.llnl.util.tty.log.keyboard_input(stdin: IO[str] | None)[source]¶
Bases:
preserve_terminal_settingsContext manager to disable line editing and echoing.
Use this with
sys.stdinfor keyboard input, e.g.:with keyboard_input(sys.stdin) as kb: while True: kb.check_fg_bg() r, w, x = select.select([sys.stdin], [], []) # ... do something with keypresses ...
The
keyboard_inputcontext manager disables canonical (line-based) input and echoing, so that keypresses are available on the stream immediately, and they are not printed to the terminal. Typically, standard input is line-buffered, which means keypresses won’t be sent until the user hits return. In this mode, a user can hit, e.g.,v, and it will be read on the other end of the pipe immediately but not printed.The handler takes care to ensure that terminal changes only take effect when the calling process is in the foreground. If the process is backgrounded, canonical mode and echo are re-enabled. They are disabled again when the calling process comes back to the foreground.
This context manager works through a single signal handler for
SIGTSTP, along with a poolling routine calledcheck_fg_bg(). Here are the relevant states, transitions, and POSIX signals:[Running] -------- Ctrl-Z sends SIGTSTP ------------. [ in FG ] <------- fg sends SIGCONT --------------. | ^ | | | fg (no signal) | | | | v [Running] <------- bg sends SIGCONT ---------- [Stopped] [ in BG ] [ in BG ]
We handle all transitions except for
SIGTSTPgenerated by Ctrl-Z by periodically callingcheck_fg_bg(). This routine notices if we are in the background with canonical mode or echo disabled, or if we are in the foreground without canonical disabled and echo enabled, and it fixes the terminal settings in response.check_fg_bg()works except for when the process is stopped withSIGTSTP. We cannot rely on a periodic timer in this case, as it may not rrun before the process stops. We therefore restore terminal settings in theSIGTSTPhandler.Additional notes:
We mostly use polling here instead of a SIGARLM timer or a thread. This is to avoid the complexities of many interrupts, which seem to make system calls (like I/O) unreliable in older Python versions (2.6 and 2.7). See these issues for details:
There are essentially too many ways for asynchronous signals to go wrong if we also have to support older Python versions, so we opt not to use them.
SIGSTOPcan stop a process (in the foreground or background), but it can’t be caught. Because of this, we can’t fix any terminal settings onSIGSTOP, and the terminal will be left withICANONandECHOdisabled until it is resumes execution.Technically, a process could be sent
SIGTSTPwhile running in the foreground, without the shell backgrounding that process. This doesn’t happen in practice, and we assume thatSIGTSTPalways means that defaults should be restored.We rely on
termiossupport. Without it, or if the stream isn’t a TTY,keyboard_inputhas no effect.
- spack.llnl.util.tty.log.log_output(*args, **kwargs)[source]¶
Context manager that logs its output to a file.
In the simplest case, the usage looks like this:
with log_output('logfile.txt'): # do things ... output will be logged
Any output from the with block will be redirected to
logfile.txt. If you also want the output to be echoed tostdout, use theechoparameter:with log_output('logfile.txt', echo=True): # do things ... output will be logged and printed out
The following is available on Unix only. No-op on Windows. And, if you just want to echo some stuff from the parent, use
force_echo:with log_output('logfile.txt', echo=False) as logger: # do things ... output will be logged with logger.force_echo(): # things here will be echoed *and* logged
See individual log classes for more information.
This method is actually a factory serving a per platform (unix vs windows) log_output class
- class spack.llnl.util.tty.log.nixlog(filename: str, echo=False, debug=0, buffer=False, env=None, filter_fn=None, append=False)[source]¶
Bases:
objectUnder the hood, we spawn a daemon and set up a pipe between this process and the daemon. The daemon writes our output to both the file and to stdout (if echoing). The parent process can communicate with the daemon to tell it when and when not to echo; this is what force_echo does. You can also enable/disable echoing by typing
v.We use OS-level file descriptors to do the redirection, which redirects output for subprocesses and system calls.
- class spack.llnl.util.tty.log.preserve_terminal_settings(stdin: IO[str] | None)[source]¶
Bases:
objectContext manager to preserve terminal settings on a stream.
Stores terminal settings before the context and ensures they are restored after. Ensures that things like echo and canonical line mode are not left disabled if terminal settings in the context are not properly restored.