validate:launcher: Support mixed str/bytes control sequences.

It is not safe for `_preformat_levels` to assume that all of the fields in a
`TerminalController` have the same type; at least in my environment, some of
these fields are populated with `bytes` while others remain strings.

This change conditionally applies decoding to each control sequence separately
using a helper function `_as_string`.  As a side-effect, it also eliminates some
code repetition in `_preformat_levels`.

Closes #50.
This commit is contained in:
Brady J. Garvin 2020-01-05 14:09:07 -06:00
parent 195d3a3edc
commit 06822b519b

View file

@ -644,22 +644,19 @@ def logLevelName(level):
return format % (_LEVEL_NAMES[level - 1], ) return format % (_LEVEL_NAMES[level - 1], )
def _as_string(string_or_bytes):
return string_or_bytes.decode() if isinstance(string_or_bytes, bytes) else string_or_bytes
def _preformatLevels(enableColorOutput): def _preformatLevels(enableColorOutput):
terminal_controller = TerminalController() terminal_controller = TerminalController()
for level in ERROR, WARN, FIXME, INFO, DEBUG, LOG: for level in ERROR, WARN, FIXME, INFO, DEBUG, LOG:
if enableColorOutput: if enableColorOutput:
if isinstance(terminal_controller.BOLD, bytes): formatter = ''.join(
formatter = ''.join( (_as_string(terminal_controller.BOLD),
(terminal_controller.BOLD.decode(), _as_string(getattr(terminal_controller, COLORS[level])),
getattr(terminal_controller, COLORS[level]).decode(), logLevelName(level),
logLevelName(level), _as_string(terminal_controller.NORMAL)))
terminal_controller.NORMAL.decode()))
else:
formatter = ''.join(
(terminal_controller.BOLD,
getattr(terminal_controller, COLORS[level]),
logLevelName(level),
terminal_controller.NORMAL))
else: else:
formatter = logLevelName(level) formatter = logLevelName(level)
_FORMATTED_LEVELS.append(formatter) _FORMATTED_LEVELS.append(formatter)