def __init__(self, output_stream): TerminalInterface.DumbBackend.__init__(self, output_stream) curses.setupterm(fd = output_stream.fileno()) # Move to beginning of line self.MOVE_TO_BOL = curses.tigetstr('cr') # Clear to end of line self.CLEAR_TO_EOL = curses.tigetstr('el') # Colors self.RESET_FG_BG = curses.tigetstr('op').decode('ascii') set_fg = curses.tigetstr('setf').decode('ascii') if set_fg: for i,color in zip(range(len(self.__COLORS)), self.__COLORS): setattr(self, color, curses.tparm(set_fg, i).decode('ascii') or '') set_fg_ansi = curses.tigetstr('setaf').decode('ascii') if set_fg_ansi: for i,color in zip(range(len(self.__ANSICOLORS)), self.__ANSICOLORS): setattr(self, color, curses.tparm(set_fg_ansi, i).decode('ascii') or '') set_bg = curses.tigetstr('setb').decode('ascii') if set_bg: for i,color in zip(range(len(self.__COLORS)), self.__COLORS): setattr(self, 'BG_'+color, curses.tparm(set_bg, i).decode('ascii') or '') set_bg_ansi = curses.tigetstr('setab').decode('ascii') if set_bg_ansi: for i,color in zip(range(len(self.__ANSICOLORS)), self.__ANSICOLORS): setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i).decode('ascii') or '')
def __init__(self, color=True, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) self._color = color and _stderr_supports_color() if self._color: # The curses module has some str/bytes confusion in # python3. Until version 3.2.3, most methods return # bytes, but only accept strings. In addition, we want to # output these strings with the logging module, which # works with unicode strings. The explicit calls to # unicode() below are harmless in python2 but will do the # right conversion in python 3. fg_color = (curses.tigetstr("setaf") or curses.tigetstr("setf") or "") if (3, 0) < sys.version_info < (3, 2, 3): fg_color = unicode(fg_color, "ascii") self._colors = { logging.DEBUG: unicode(curses.tparm(fg_color, 4), # Blue "ascii"), logging.INFO: unicode(curses.tparm(fg_color, 2), # Green "ascii"), logging.WARNING: unicode(curses.tparm(fg_color, 3), # Yellow "ascii"), logging.ERROR: unicode(curses.tparm(fg_color, 1), # Red "ascii"), } self._normal = unicode(curses.tigetstr("sgr0"), "ascii")
def printwyx(self, window, coord, arg, color = None, attribute = None): if self.cursescolors == True: try: if color or attribute: attr = 0 if color: attr |= self.color[color] if attribute: attr |= self.attribute[attribute] if coord: window.addstr(coord[0], coord[1], arg, attr) else: window.addstr(arg, attr) elif coord: window.addstr(coord[0], coord[1], arg) else: window.addstr(arg) except curses.error: pass else: coordstr = "" if coord: coordstr = curses.tparm(curses.tigetstr("cup"), coord[0], coord[1]) colorstr = self.attribute['normal'] if color: colorstr += self.color[color] if attribute: colorstr += self.attribute[attribute] clr_eol = curses.tparm(curses.tigetstr("el")) curses.putp(coordstr + colorstr + arg + clr_eol)
def __init__(self, term_stream=sys.stdout): try: import curses except: return if not term_stream.isatty(): return try: curses.setupterm() except: return self.COLS = curses.tigetnum('cols') self.LINES = curses.tigetnum('lines') for capability in self._STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') setattr(self, attrib, self._tigetstr(cap_name) or '') set_fg = self._tigetstr('setf') if set_fg: for i,color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, color, curses.tparm(set_fg, i) or '') set_fg_ansi = self._tigetstr('setaf') if set_fg_ansi: for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, color, curses.tparm(set_fg_ansi, i) or '') set_bg = self._tigetstr('setb') if set_bg: for i,color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '') set_bg_ansi = self._tigetstr('setab') if set_bg_ansi: for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
def __init__(self, term_stream=sys.stdout): """ Create a `TerminalController` and initialize its attributes with appropriate values for the current terminal. `term_stream` is the stream that will be used for terminal output; if this stream is not a tty, then the terminal is assumed to be a dumb terminal (i.e., have no capabilities). """ # Curses isn't available on all platforms try: import curses except: return # If the stream isn't a tty, then assume it has no capabilities. if not term_stream.isatty(): return # Check the terminal type. If we fail, then assume that the # terminal has no capabilities. try: curses.setupterm() except: return # Look up numeric capabilities. self.COLS = curses.tigetnum('cols') self.LINES = curses.tigetnum('lines') # Look up string capabilities. for capability in self._STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') setattr(self, attrib, self._tigetstr(cap_name) or '') # Colors set_fg = self._tigetstr('setf') if set_fg: for i, color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, color, curses.tparm(set_fg, i) or '') set_fg_ansi = self._tigetstr('setaf') if set_fg_ansi: for i, color in zip( range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, color, curses.tparm(set_fg_ansi, i) or '') set_bg = self._tigetstr('setb') if set_bg: for i, color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, 'BG_' + color, curses.tparm(set_bg, i) or '') set_bg_ansi = self._tigetstr('setab') if set_bg_ansi: for i, color in zip( range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr( self, 'BG_' + color, curses.tparm( set_bg_ansi, i) or '')
def add_color_to_string(string, color, stream=sys.stdout, bold=False, force=False): """Format the string to be printed with the given color. Insert formatting characters that, when printed on a terminal, will make the given string appear with the given foreground color if the stream passed has color support. Else return the string as it is. string (string): the string to color. color (int): the color as a colors constant, like colors.BLACK. stream (fileobj): a file-like object (that adheres to the API declared in the `io' package). Defaults to sys.stdout. bold (bool): True if the string should be bold. force (bool): True if the string should be formatted even if the given stream has no color support. return (string): the formatted string. """ if force or has_color_support(stream): return "%s%s%s%s" % ( curses.tparm(curses.tigetstr("setaf"), color).decode('ascii') if color != colors.BLACK else "", curses.tparm(curses.tigetstr("bold")).decode('ascii') if bold else "", string, curses.tparm(curses.tigetstr("sgr0")).decode('ascii') ) else: return string
def __init__(self, term_stream=sys.stdout): """ Create a `TerminalController` and initialize its attributes with appropriate values for the current terminal. `term_stream` is the stream that will be used for terminal output; if this stream is not a tty, then the terminal is assumed to be a dumb terminal (i.e., have no capabilities). """ # Curses isn't available on all platforms try: import curses except Error: return # If the stream isn't a tty, then assume it has no capabilities. if not term_stream.isatty(): return # Check the terminal type. If we fail, then assume that the # terminal has no capabilities. try: curses.setupterm() except Error: return # Look up numeric capabilities. # return -2 if capname is not a numberic capability # return -1 if it is canceled or absent from terminal description self.COLS = curses.tigetnum('cols') self.LINES = curses.tigetnum('lines') # Look up string capabilities. for capability in self._STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') setattr(self, attrib, self._tigetstr(cap_name) or '') # Colors set_fg = self._tigetstr('setf') # curses.tparm instantiates the string with the supplied parameters, # where str should be a parameterized string obtained from the terminfo # database. E.g tparm(tigetstr("cup", 5, 3) could result in # '\033[6;4H', the exact result depending on terminal type if set_fg: for index, color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, color, curses.tparm(set_fg, index) or '') set_fg_ansi = self._tigetstr('setaf') if set_fg_ansi: for index, color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, color, curses.tparm(set_fg_ansi, index) or '') set_bg = self._tigetstr('setb') if set_bg: for index, color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, 'BG_'+color, curses.tparm(set_bg, index) or '') set_bg_ansi = self._tigetstr('setab') if set_bg_ansi: for index, color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, index) or '')
def __init__(self, color, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) self._color = color if color: # The curses module has some str/bytes confusion in python3. # Most methods return bytes, but only accept strings. # The explict calls to unicode() below are harmless in python2, # but will do the right conversion in python3. try: fg_color = unicode(curses.tigetstr("setaf") or curses.tigetstr("setf") or "", "ascii") self._colors = { logging.DEBUG: unicode(curses.tparm(fg_color, 4), # Blue "ascii"), logging.INFO: unicode(curses.tparm(fg_color, 2), # Green "ascii"), logging.WARNING: unicode(curses.tparm(fg_color, 3), # Yellow "ascii"), logging.ERROR: unicode(curses.tparm(fg_color, 1), # Red "ascii"), } self._normal = unicode(curses.tigetstr("sgr0"), "ascii") except: # curses is not setup when not running in a tty (service) bash_colors = dict(red=31, green=32, yellow=33, blue=34, pink=35, cyan=36, white=37) self._colors = { logging.DEBUG: '\033[%s;%sm' % (0, bash_colors['blue']), logging.INFO: '\033[%s;%sm' % (0, bash_colors['green']), logging.WARNING: '\033[%s;%sm' % (0, bash_colors['yellow']), logging.ERROR: '\033[%s;%sm' % (0, bash_colors['red']) } self._normal = '\033[0m'
def colourise_output(start, line, end="reset"): """ Wrapper method to return colourised output when running in a terminal. :param start: One of 'red', 'green', 'yellow' or 'cyan' :type start: str. :param line: Text to be colourised. :type line: str. :param end: Typically, 'reset' to clear the colourisation. :type end: str. :returns: str. """ # Simple coloured output if not is_term(): return line if colourise_output.init == 0: curses.setupterm() colourise_output.init = 1 colours = { "reset": curses.tparm(curses.tigetstr("op")), "red": curses.tparm(curses.tigetstr("setaf"), curses.COLOR_RED), "green": curses.tparm(curses.tigetstr("setaf"), curses.COLOR_GREEN), "yellow": curses.tparm(curses.tigetstr("setaf"), curses.COLOR_YELLOW), "cyan": curses.tparm(curses.tigetstr("setaf"), curses.COLOR_CYAN), } return colours[start] + line + colours[end]
def __init__(self, width=None): "Constructor." self._progress = None self._lines = 0 self._PADDING = 7 curses.setupterm() fgColorSeq = curses.tigetstr('setaf') or curses.tigetstr('setf') or '' colorIndex = getattr(curses, 'COLOR_WHITE') self._fgcolour = curses.tparm(fgColorSeq, colorIndex) bgColorSeq = curses.tigetstr('setab') or curses.tigetstr('setb') or '' colorIndex = getattr(curses, 'COLOR_BLACK') self._bgcolour = curses.tparm(bgColorSeq, colorIndex) self._control = {} for control in _CONTROLS: # Set the control escape sequence self._control[control] = curses.tigetstr(_CONTROLS[control]) or '' self._value = {} for value in _VALUES: # Set terminal related values self._value[value] = curses.tigetnum(_VALUES[value]) if width and width < self._value["COLUMNS"] - self._PADDING: self._width = width else: self._width = self._value["COLUMNS"] - self._PADDING
def render(char_map, characters, color_map=None): """ Takes ascii & color data, and display it on the screen """ import curses curses.setupterm() fg_normal = curses.tigetstr('sgr0') fg_colors = [curses.tparm(curses.tigetstr('setaf'), i) for i in range(8)] attr_bold = curses.tparm(curses.tigetstr('bold'), curses.A_BOLD) attr_normal = curses.tparm(curses.tigetstr('sgr0'), curses.A_NORMAL) def set_color(fg=None): if fg is None: return fg_normal + attr_normal if fg in range(0, 8): return fg_colors[fg] if fg in range(8, 16): return fg_colors[fg-8] + attr_bold return '' for y in range(len(char_map)): for x in range(len(char_map[y])): if color_map is not None: print(set_color(color_map[y][x]), end='') print(characters[char_map[y][x]], end='') print('') if color_map is not None: print(set_color(), end='')
def _SetupColours(): """Initializes the colour constants. """ # pylint: disable=W0603 # due to global usage global _INFO_SEQ, _WARNING_SEQ, _ERROR_SEQ, _RESET_SEQ # Don't use colours if stdout isn't a terminal if not sys.stdout.isatty(): return try: import curses except ImportError: # Don't use colours if curses module can't be imported return curses.setupterm() _RESET_SEQ = curses.tigetstr("op") setaf = curses.tigetstr("setaf") _INFO_SEQ = curses.tparm(setaf, curses.COLOR_GREEN) _WARNING_SEQ = curses.tparm(setaf, curses.COLOR_YELLOW) _ERROR_SEQ = curses.tparm(setaf, curses.COLOR_RED)
def move_cursor(direction, amount=1, stream=sys.stdout, erase=False): """Move the cursor. If the stream is a TTY, print characters that will move the cursor in the given direction and optionally erase the line. Else do nothing. direction (int): the direction as a directions constant, like directions.UP. stream (fileobj): a file-like object (that adheres to the API declared in the `io' package). Defaults to sys.stdout. erase (bool): True if the line the cursor ends on should be erased. """ if stream.isatty(): if direction == directions.UP: print(curses.tparm(curses.tigetstr("cuu"), amount), file=stream, end='') elif direction == directions.DOWN: print(curses.tparm(curses.tigetstr("cud"), amount), file=stream, end='') elif direction == directions.LEFT: print(curses.tparm(curses.tigetstr("cub"), amount), file=stream, end='') elif direction == directions.RIGHT: print(curses.tparm(curses.tigetstr("cuf"), amount), file=stream, end='') if erase: print(curses.tparm(curses.tigetstr("el")), file=stream, end='') stream.flush()
def __init__(self, color, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) self._color = color if color: # The curses module has some str/bytes confusion in python3. # Most methods return bytes, but only accept strings. # The explict calls to unicode() below are harmless in python2, # but will do the right conversion in python3. fg_color = unicode(curses.tigetstr("setaf") or curses.tigetstr("setf") or "", "ascii") self._colors = { logging.DEBUG: unicode( curses.tparm(fg_color, curses.COLOR_CYAN), "ascii"), logging.INFO: unicode( curses.tparm(fg_color, curses.COLOR_GREEN), "ascii"), logging.WARNING: unicode( curses.tparm(fg_color, curses.COLOR_YELLOW), # Yellow "ascii"), logging.ERROR: unicode( curses.tparm(fg_color, curses.COLOR_RED), # Red "ascii"), } self._normal = unicode(curses.tigetstr("sgr0"), "ascii")
def __init__(self, color, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) self._color = color if color: fg_color = (curses.tigetstr("setaf") or curses.tigetstr("setf") or "") if (3, 0) < sys.version_info < (3, 2, 3): fg_color = six.text_type(fg_color, "ascii") self._colors = { logging.DEBUG: six.text_type( curses.tparm(fg_color, 4), "ascii" ), # Blue logging.INFO: six.text_type( curses.tparm(fg_color, 2), "ascii" ), # Green logging.WARNING: six.text_type( curses.tparm(fg_color, 3), "ascii" ), # Yellow logging.ERROR: six.text_type( curses.tparm(fg_color, 1), "ascii" ), # Red } self._normal = six.text_type(curses.tigetstr("sgr0"), "ascii")
def __init__(self, console, *args, **kwargs): #logging.Formatter.__init__(self, *args, **kwargs) logging.Formatter.__init__(self, "%(asctime)s - %(name)s - %(levelname)s - %(message)s") color = False if console: if curses and sys.stderr.isatty(): try: curses.setupterm() if curses.tigetnum("colors") > 0: color = True except Exception: pass self._color = color if color: # The curses module has some str/bytes confusion in python3. # Most methods return bytes, but only accept strings. # The explict calls to unicode() below are harmless in python2, # but will do the right conversion in python3. fg_color = unicode(curses.tigetstr("setaf") or curses.tigetstr("setf") or "", "ascii") self._colors = { logging.DEBUG: unicode(curses.tparm(fg_color, 4), # Blue "ascii"), logging.INFO: unicode(curses.tparm(fg_color, 2), # Green "ascii"), logging.WARNING: unicode(curses.tparm(fg_color, 3), # Yellow "ascii"), logging.ERROR: unicode(curses.tparm(fg_color, 1), # Red "ascii"), } self._normal = unicode(curses.tigetstr("sgr0"), "ascii")
def _lookup_caps(): import curses from .utils import to_ascii # Look up numeric capabilities. colors.COLS = curses.tigetnum('cols') colors.LINES = curses.tigetnum('lines') # Look up string capabilities. for capability in _STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') setattr(colors, attrib, _tigetstr(cap_name) or '') # Colors set_fg = _tigetstr('setf') if set_fg: for i, color in zip(list(range(len(_COLORS))), _COLORS): setattr(colors, color, to_ascii(curses.tparm(set_fg.encode('utf-8'), i)) or '') set_fg_ansi = _tigetstr('setaf') if set_fg_ansi: for i, color in zip(list(range(len(_ANSICOLORS))), _ANSICOLORS): setattr(colors, color, to_ascii(curses.tparm(set_fg_ansi.encode('utf-8'), i)) or '') set_bg = _tigetstr('setb') if set_bg: for i, color in zip(list(range(len(_COLORS))), _COLORS): setattr(colors, 'BG_'+color, to_ascii(curses.tparm(set_bg.encode('utf-8'), i)) or '') set_bg_ansi = _tigetstr('setab') if set_bg_ansi: for i, color in zip(list(range(len(_ANSICOLORS))), _ANSICOLORS): setattr(colors, 'BG_'+color, to_ascii(curses.tparm(set_bg_ansi.encode('utf-8'), i)) or '')
def __init__(self, term_stream=sys.stdout): """ Create a `TerminalController` and initialize its attributes with appropriate values for the current terminal. `term_stream` is the stream that will be used for terminal output; if this stream is not a tty, then the terminal is assumed to be a dumb terminal (i.e., have no capabilities). """ # Curses isn't available on all platforms try: import curses except: return # If the stream isn't a tty, then assume it has no capabilities. try: if not term_stream.isatty(): return except: return # Check the terminal type. If we fail, then assume that the # terminal has no capabilities. try: curses.setupterm() except: return # Look up numeric capabilities. self.COLS = curses.tigetnum('cols') self.LINES = curses.tigetnum('lines') # Look up string capabilities. for capability in self._STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') setattr(self, attrib, self._tigetstr(cap_name) or '') self.END = self.BOL + self.RIGHT * (self.COLS - 10) # Colors set_fg = self._tigetstr('setf') if set_fg: for i, color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, color, curses.tparm(set_fg, i) or '') set_fg_ansi = self._tigetstr('setaf') if set_fg_ansi: for i, color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, color, curses.tparm(set_fg_ansi, i) or '') set_bg = self._tigetstr('setb') if set_bg: for i, color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, 'BG_' + color, curses.tparm(set_bg, i) or '') set_bg_ansi = self._tigetstr('setab') if set_bg_ansi: for i, color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, 'BG_' + color, curses.tparm(set_bg_ansi, i) or '')
def set_fg_colors(self): if tigetstr('setaf'): for i, color in enumerate(ansi_colors): setattr(self, color, tparm(tigetstr('setaf'), i)) elif curses.tigetstr('setf'): for i, color in enumerate(colors): setattr(self, color, tparm(tigetstr('setf'), i))
def __init__(self, term_stream=sys.stdout): # Curses isn't available on all platforms try: import curses except: return # If the stream isn't a tty, then assume it has no capabilities. if not hasattr(term_stream, 'isatty') or not term_stream.isatty(): return # Check the terminal type. If we fail, then assume that the # terminal has no capabilities. try: curses.setupterm() except: return # Look up numeric capabilities. self.COLS = curses.tigetnum('cols') self.LINES = curses.tigetnum('lines') # Look up string capabilities. for capability in self._STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') setattr(self, attrib, self._escape_code(self._tigetstr(cap_name))) # Colors set_fg = self._tigetstr('setf') if set_fg: if not isinstance(set_fg, bytes): set_fg = set_fg.encode('utf-8') for i,color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, color, self._escape_code(curses.tparm((set_fg), i))) set_fg_ansi = self._tigetstr('setaf') if set_fg_ansi: if not isinstance(set_fg_ansi, bytes): set_fg_ansi = set_fg_ansi.encode('utf-8') for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, color, self._escape_code(curses.tparm((set_fg_ansi), i))) set_bg = self._tigetstr('setb') if set_bg: if not isinstance(set_bg, bytes): set_bg = set_bg.encode('utf-8') for i,color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, 'BG_'+color, self._escape_code(curses.tparm((set_bg), i))) set_bg_ansi = self._tigetstr('setab') if set_bg_ansi: if not isinstance(set_bg_ansi, bytes): set_bg_ansi = set_bg_ansi.encode('utf-8') for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, 'BG_'+color, self._escape_code(curses.tparm((set_bg_ansi), i)))
def __init__(self, term_stream=sys.stdout): # Curses isn't available on all platforms try: import curses except: return # If the stream isn't a tty, then assume it has no capabilities. if not hasattr(term_stream, 'isatty') or not term_stream.isatty(): return # Check the terminal type. If we fail, then assume that the # terminal has no capabilities. try: curses.setupterm() except: return # Look up numeric capabilities. self.COLS = curses.tigetnum('cols') self.LINES = curses.tigetnum('lines') # Look up string capabilities. for capability in self._STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') setattr(self, attrib, self._escape_code(self._tigetstr(cap_name))) # Colors set_fg = self._tigetstr('setf') if set_fg: if not isinstance(set_fg, bytes): set_fg = set_fg.encode('utf-8') for i, color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, color, self._escape_code(curses.tparm((set_fg), i))) set_fg_ansi = self._tigetstr('setaf') if set_fg_ansi: if not isinstance(set_fg_ansi, bytes): set_fg_ansi = set_fg_ansi.encode('utf-8') for i, color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, color, self._escape_code(curses.tparm((set_fg_ansi), i))) set_bg = self._tigetstr('setb') if set_bg: if not isinstance(set_bg, bytes): set_bg = set_bg.encode('utf-8') for i, color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, 'BG_' + color, self._escape_code(curses.tparm((set_bg), i))) set_bg_ansi = self._tigetstr('setab') if set_bg_ansi: if not isinstance(set_bg_ansi, bytes): set_bg_ansi = set_bg_ansi.encode('utf-8') for i, color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, 'BG_' + color, self._escape_code(curses.tparm((set_bg_ansi), i)))
def _init(): """ Initialize attributes with appropriate values for the current terminal. `_term_stream` is the stream that will be used for terminal output; if this stream is not a tty, then the terminal is assumed to be a dumb terminal (i.e., have no capabilities). """ def _tigetstr(cap_name): # String capabilities can include "delays" of the form "$<2>". # For any modern terminal, we should be able to just ignore # these, so strip them out. import curses cap = curses.tigetstr(cap_name) or '' return re.sub(r'\$<\d+>[/*]?', '', cap) _term_stream = sys.stdout # Curses isn't available on all platforms try: import curses except: sys.stderr.write("INFO: no curses support: you won't see colors\n") return # If the stream isn't a tty, then assume it has no capabilities. if not _term_stream.isatty(): return # Check the terminal type. If we fail, then assume that the # terminal has no capabilities. try: curses.setupterm() except: return # Look up numeric capabilities. colors.COLS = curses.tigetnum('cols') colors.LINES = curses.tigetnum('lines') # Look up string capabilities. for capability in _STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') setattr(colors, attrib, _tigetstr(cap_name) or '') # Colors set_fg = _tigetstr('setf') if set_fg: for i, color in zip(range(len(_COLORS)), _COLORS): setattr(colors, color, curses.tparm(set_fg, i) or '') set_fg_ansi = _tigetstr('setaf') if set_fg_ansi: for i, color in zip(range(len(_ANSICOLORS)), _ANSICOLORS): setattr(colors, color, curses.tparm(set_fg_ansi, i) or '') set_bg = _tigetstr('setb') if set_bg: for i, color in zip(range(len(_COLORS)), _COLORS): setattr(colors, 'BG_'+color, curses.tparm(set_bg, i) or '') set_bg_ansi = _tigetstr('setab') if set_bg_ansi: for i, color in zip(range(len(_ANSICOLORS)), _ANSICOLORS): setattr(colors, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
def get_codes_curses(fd): """get capabilities and color codes using the curses module""" import curses curses.setupterm(None, fd) codes = dict((name, curses.tigetstr(code)) for name, code in CAPABILITY) for index, name in enumerate(ANSI_COLORS): codes[name] = curses.tparm(codes['A_COLOR'], index) codes['BG_'+name] = curses.tparm(codes['A_BG_COLOR'], index) return codes
def __init__(self, term_stream=sys.stdout, escape=False): """ Create a `TerminalController` and initialize its attributes with appropriate values for the current terminal. `term_stream` is the stream that will be used for terminal output; if this stream is not a tty, then the terminal is assumed to be a dumb terminal (i.e., have no capabilities). """ # when printing things out on lines accepting user input control # characters must be wrapped in special characters for correct # word wrapping, always wrap when escape == True self.escape = escape # Curses isn't available on all platforms try: import curses except: return # If the stream isn't a tty, then assume it has no capabilities. if not term_stream.isatty(): return # Check the terminal type. If we fail, then assume that the # terminal has no capabilities. try: curses.setupterm() except: return # Look up numeric capabilities. self.COLS = curses.tigetnum("cols") self.LINES = curses.tigetnum("lines") # Look up string capabilities. for capability in self._STRING_CAPABILITIES: (attrib, cap_name) = capability.split("=") setattr(self, attrib, self._tigetstr(cap_name) or "") # Colors set_fg = self._tigetstr("setf") if set_fg: for i, color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, color, curses.tparm(set_fg, i) or "") set_fg_ansi = self._tigetstr("setaf") if set_fg_ansi: for i, color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, color, curses.tparm(set_fg_ansi, i) or "") set_bg = self._tigetstr("setb") if set_bg: for i, color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, "BG_" + color, curses.tparm(set_bg, i) or "") set_bg_ansi = self._tigetstr("setab") if set_bg_ansi: for i, color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, "BG_" + color, curses.tparm(set_bg_ansi, i) or "")
def __init__(self, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) fg_color = curses.tigetstr("setaf") or curses.tigetstr("setf") or "" self._colors = { logging.DEBUG: curses.tparm(fg_color, 4), # Blue logging.INFO: curses.tparm(fg_color, 2), # Green logging.WARNING: curses.tparm(fg_color, 3), # Yellow logging.ERROR: curses.tparm(fg_color, 1), # Red } self._normal = curses.tigetstr("sgr0")
def __init__(self): self.use_color = sys.stdout.isatty() if self.use_color: curses.setupterm() setf = curses.tigetstr('setaf') bold = curses.tigetstr('bold') self.red = curses.tparm(setf, 1) + bold self.green = curses.tparm(setf, 2) + bold self.yellow = curses.tparm(setf, 3) + bold self.nocolor = curses.tigetstr('sgr0')
def color_map(self): if self._color_map is None: fg_color = curses.tigetstr("setaf") or curses.tigetstr("setf") or "" self._color_map = { logging.INFO: unicode(curses.tparm(fg_color, 2), "ascii"), # Green logging.WARNING: unicode(curses.tparm(fg_color, 3), "ascii"), # Yellow logging.ERROR: unicode(curses.tparm(fg_color, 1), "ascii"), # Red logging.CRITICAL: unicode(curses.tparm(fg_color, 1), "ascii"), # Red } self._normal_color = unicode(curses.tigetstr("sgr0"), "ascii") return self._color_map
def jump(row, col=0): try: tparm(tigetstr("sc")) os.system( "tput sc && tput civis && tput clear && tput cup %d,%d " % (row, col)) os.system("tput cnorm") yield finally: input("End") os.system("tput clear && tput sgr0 && tput rc")
def check(self, xthing, xlen): """ return OK or FAIL """ import curses curses.setupterm() cap = curses.tigetstr('setf') GREEN = curses.tparm(cap, 2) RED = curses.tparm(cap, 4) RESET = curses.tparm(cap, 9) if len(xthing) != xlen: print "...........[%sFAIL%s]" % (RED, RESET) else: print "...........[%sOK%s]" %(GREEN,RESET)
def __init__(self): self.use_color = utils.supportsTerminalColors() if self.use_color: try: curses.setupterm() setf = curses.tigetstr('setaf') or '' bold = curses.tigetstr('bold') or '' self.red = (curses.tparm(setf, 1) if setf != '' else '') + bold self.green = (curses.tparm(setf, 2) if setf != '' else '') + bold self.yellow = (curses.tparm(setf, 3) if setf != '' else '') + bold self.nocolor = curses.tigetstr('sgr0') or '' except Exception: pass
def _move_up(self): assert self._term_caps is not None # Explicitly move to beginning of line, fixes things up # when there was a ^C or ^Z printed to the terminal. move_x = curses.tparm(self._term_caps["move_x"].encode("latin1"), 0) move_x = move_x.decode("latin1") move_up = curses.tparm(self._term_caps["move_up"].encode("latin1")) move_up = move_up.decode("latin1") click.echo(move_x + move_up, nl=False, err=True)
def check(self, xthing, xlen): """ return OK or FAIL """ import curses curses.setupterm() cap = curses.tigetstr('setf') GREEN = curses.tparm(cap, 2) RED = curses.tparm(cap, 4) RESET = curses.tparm(cap, 9) if len(xthing) != xlen: print "...........[%sFAIL%s]" % (RED, RESET) else: print "...........[%sOK%s]" % (GREEN, RESET)
def alternating_bg(output): if stdout.isatty(): curses.setupterm() if curses.tigetnum("colors") == 256: c0 = curses.tigetstr('sgr0').decode() c1 = curses.tparm(curses.tigetstr('setab'), 236).decode() c2 = curses.tparm(curses.tigetstr('setab'), 232).decode() return "\n".join((c1 if i % 2 else c2) + line + c0 for i, line in enumerate(output.split("\n"))) return output
def get_colors(): """Just returns the CSI codes for red, green, magenta, and reset color.""" try: curses.setupterm() fg_color = curses.tigetstr("setaf") or curses.tigetstr("setf") or "" red = str(curses.tparm(fg_color, 1), "ascii") green = str(curses.tparm(fg_color, 2), "ascii") magenta = str(curses.tparm(fg_color, 5), "ascii") no_color = str(curses.tigetstr("sgr0"), "ascii") except curses.error: red, green, magenta = "", "", "" no_color = "" return red, green, magenta, no_color
def __init__(self, color=True, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) self._color = color and _stderr_supports_color() if self._color: fg_color = (curses.tigetstr("setaf") or curses.tigetstr("setf") or "") self._colors = { logging.DEBUG: curses.tparm(fg_color, 4), # Blue logging.INFO: curses.tparm(fg_color, 2), # Green logging.WARNING: curses.tparm(fg_color, 3), # Yellow logging.ERROR: curses.tparm(fg_color, 1), # Red } self._normal = curses.tigetstr("sgr0")
def __init__(self, color, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) self._color = color if color: fg_color = curses.tigetstr("setaf") or curses.tigetstr("setf") or "" self._colors = { logging.ERROR: curses.tparm(fg_color, 1), logging.INFO: curses.tparm(fg_color, 2), logging.CRITICAL: curses.tparm(fg_color, 3), logging.WARNING: curses.tparm(fg_color, 5), logging.DEBUG: curses.tparm(fg_color, 4), } self._normal = curses.tigetstr("sgr0")
def _init_colors(self): curses = self._get_curses() if not curses: return ### Set foreground colors setaf_param = curses.tigetstr("setaf") for i, cname in enumerate(ANSI_COLOR_NAMES): self._set_fore_color(cname, curses.tparm(setaf_param, i)) ### Set background colors setab_param = curses.tigetstr("setab") for i, cname in enumerate(ANSI_COLOR_NAMES): self._set_back_color(cname, curses.tparm(setab_param, i)) self.color_enabled = True
def __init__(self): if sys.stdout.isatty(): import curses curses.setupterm() self._bold = (curses.tigetstr('bold') or b'').decode() set_foreground = curses.tigetstr('setaf') or b'' self._red = curses.tparm(set_foreground, curses.COLOR_RED).decode() self._green = curses.tparm(set_foreground, curses.COLOR_GREEN).decode() self._reset = (curses.tigetstr('sgr0') or b'').decode() else: self._bold = '' self._red = '' self._green = '' self._reset = ''
def __init__(self, color, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) self._color = color if color: fg_color = (curses.tigetstr("setaf") or curses.tigetstr("setf") or "") self._colors = { logging.ERROR: curses.tparm(fg_color, 1), logging.INFO: curses.tparm(fg_color, 2), logging.CRITICAL: curses.tparm(fg_color, 3), logging.WARNING: curses.tparm(fg_color, 5), logging.DEBUG: curses.tparm(fg_color, 4) } self._normal = curses.tigetstr("sgr0")
def __init__(self, level=logging.NOTSET): logging.Handler.__init__(self, level) import curses curses.setupterm() if curses.tigetnum('colors') < 8: raise EnvironmentError, 'Not enough colors available.' self.curses = curses setf = curses.tigetstr('setaf') setbg = curses.tigetstr('setab') self.colormap = { 'DEBUG': curses.tparm(setf, curses.COLOR_BLUE), 'INFO': curses.tparm(setf, curses.COLOR_GREEN), 'WARNING': curses.tparm(setf, curses.COLOR_YELLOW) + curses.tparm(curses.tigetstr('bold'), curses.A_BOLD), 'ERROR': curses.tparm(setf, curses.COLOR_RED), 'CRITICAL': curses.tparm(setf, curses.COLOR_WHITE) + curses.tparm(curses.tigetstr('bold'), curses.A_BOLD) + curses.tparm(setbg, curses.COLOR_RED), 'NOTSET': curses.tigetstr('sgr0') }
def __init__(self, color=True, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) self._color = color and _stderr_supports_color() if self._color: fg_color = (curses.tigetstr("setaf") or curses.tigetstr("setf") or "") self._colors = { logging.DEBUG: curses.tparm(fg_color, 4), # Blue logging.INFO: curses.tparm(fg_color, 2), # Green logging.WARNING: curses.tparm(fg_color, 3), # Yellow logging.ERROR: curses.tparm(fg_color, 1), # Red logging.CRITICAL: curses.tparm(fg_color, 5), # Magenta } self._normal = curses.tigetstr("sgr0")
def _init_colors(cls, ansi_cmd, native_cmd): ansi = ["black", "red", "green", "yellow", "blue", "magenta", "cyan", "white"] native = ["black", "blue", "green", "cyan", "red", "magenta", "yellow", "white"] coll = dict((name, "") for name in ansi) template = cls._tigetstr(ansi_cmd) if template: for i, name in enumerate(ansi): coll[name] = curses.tparm(template, i) else: template = cls._tigetstr(native_cmd) if template: for i, name in enumerate(ansi): coll[name] = curses.tparm(template, i) return coll
def __init__(self): if not self._instance: super(ANSIColor, self).__init__() try: curses.setupterm() except curses.error: return self['black'] = curses.tparm(curses.tigetstr('setaf'), 0).decode('utf-8') self['red'] = curses.tparm(curses.tigetstr('setaf'), 1).decode('utf-8') self['green'] = curses.tparm(curses.tigetstr('setaf'), 2).decode('utf-8') self['yellow'] = curses.tparm(curses.tigetstr('setaf'), 3).decode('utf-8') self['blue'] = curses.tparm(curses.tigetstr('setaf'), 4).decode('utf-8') self['magenta'] = curses.tparm(curses.tigetstr('setaf'), 5).decode('utf-8') self['cyan'] = curses.tparm(curses.tigetstr('setaf'), 6).decode('utf-8') self['white'] = curses.tparm(curses.tigetstr('setaf'), 7).decode('utf-8') self['bold'] = curses.tigetstr('bold').decode('utf-8') self['underline'] = curses.tigetstr('smul').decode('utf-8') self['inverse'] = curses.tigetstr('smso').decode('utf-8') self['normal'] = curses.tigetstr('sgr0').decode('utf-8')
def __init__(self, term_stream=sys.stdout): # Curses isn't available on all platforms try: import curses except ImportError: return # If the stream isn't a tty, then assume it has no capabilities. if not term_stream.isatty(): return # Check the terminal type. If we fail, then assume that the # terminal has no capabilities. try: curses.setupterm() # pylint: disable=bare-except except: return # Look up numeric capabilities. TerminalController.COLS = curses.tigetnum('cols') TerminalController.LINES = curses.tigetnum('lines') # Look up string capabilities. for capability in self._STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') setattr(self, attrib, self._tigetstr(cap_name).decode() or '') # Colors set_fg = self._tigetstr('setf') if set_fg: for i, color in zip(list(range(len(self._COLORS))), self._COLORS): setattr(self, color, curses.tparm(set_fg, i).decode() or '') set_fg_ansi = self._tigetstr('setaf') if set_fg_ansi: for i, color in zip(list(range(len(self._ANSICOLORS))), self._ANSICOLORS): setattr(self, color, curses.tparm(set_fg_ansi, i).decode() or '') set_bg = self._tigetstr('setb') if set_bg: for i, color in zip(list(range(len(self._COLORS))), self._COLORS): setattr(self, 'BG_' + color, curses.tparm(set_bg, i).decode() or '') set_bg_ansi = self._tigetstr('setab') if set_bg_ansi: for i, color in zip(list(range(len(self._ANSICOLORS))), self._ANSICOLORS): setattr(self, 'BG_' + color, curses.tparm(set_bg_ansi, i).decode() or '')
def _effect_str(effect): '''Helper function for render_effects().''' bg = False if effect.endswith('_background'): bg = True effect = effect[:-11] attr, val = _terminfo_params[effect] if attr: return curses.tigetstr(val) elif bg: return curses.tparm(curses.tigetstr('setab'), val) else: return curses.tparm(curses.tigetstr('setaf'), val)
def setup_colors(): has_colors = False if curses and sys.stdout.isatty(): try: curses.setupterm() has_colors = curses.tigetnum('colors') > 0 except: pass if has_colors: global colors fg = curses.tigetstr('setaf') or curses.tigetstr('setf') or '' colors['normal'] = curses.tigetstr('sgr0') colors['green'] = curses.tparm(fg, 2) colors['red'] = curses.tparm(fg, 1)
def __init__(self, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) fg_color = unicode(curses.tigetstr("setaf") or curses.tigetstr("setf") or "", "ascii") self._colors = { logging.DEBUG: unicode(curses.tparm(fg_color, 4), # Blue "ascii"), logging.INFO: unicode(curses.tparm(fg_color, 2), # Green "ascii"), logging.WARNING: unicode(curses.tparm(fg_color, 3), # Yellow "ascii"), logging.ERROR: unicode(curses.tparm(fg_color, 1), # Red "ascii"), } self._normal = unicode(curses.tigetstr("sgr0"), "ascii")
def __init__(self, color, *args, **kwargs): super(TornadoLogFormatter, self).__init__(*args, **kwargs) self._color = color if color: import curses curses.setupterm() fg_color = curses.tigetstr("setaf") or curses.tigetstr("setf") or "" self._colors = { logging.DEBUG: curses.tparm(fg_color, 4), # Blue logging.INFO: curses.tparm(fg_color, 2), # Green logging.WARNING: curses.tparm(fg_color, 3), # Yellow logging.ERROR: curses.tparm(fg_color, 1), # Red logging.CRITICAL: curses.tparm(fg_color, 9), # Bright Red } self._normal = curses.tigetstr("sgr0")
def __init__(self, color, *args, **kwargs): logging.Formatter.__init__(self, *args, **kwargs) self._color = color if color and curses: fg_color = unicode(curses.tigetstr("setaf") or\ curses.tigetstr("setf") or "", "ascii") self._colors = { logging.DEBUG: unicode(curses.tparm(fg_color, 2), "ascii"), logging.INFO: unicode(curses.tparm(fg_color, 6), "ascii"), logging.WARNING: unicode(curses.tparm(fg_color, 3), "ascii"), logging.ERROR: unicode(curses.tparm(fg_color, 5), "ascii"), logging.FATAL: unicode(curses.tparm(fg_color, 1), "ascii"), } self._normal = unicode(curses.tigetstr("sgr0"), "ascii")
def __init__(self, f_out: IO[str], f_err: IO[str], show_error_codes: bool) -> None: self.show_error_codes = show_error_codes # Check if we are in a human-facing terminal on a supported platform. if sys.platform not in ('linux', 'darwin'): self.dummy_term = True return force_color = int(os.getenv('MYPY_FORCE_COLOR', '0')) if not force_color and (not f_out.isatty() or not f_err.isatty()): self.dummy_term = True return # We in a human-facing terminal, check if it supports enough styling. if not CURSES_ENABLED: self.dummy_term = True return try: curses.setupterm() except curses.error: # Most likely terminfo not found. self.dummy_term = True return bold = curses.tigetstr('bold') under = curses.tigetstr('smul') set_color = curses.tigetstr('setaf') self.dummy_term = not (bold and under and set_color) if self.dummy_term: return self.NORMAL = curses.tigetstr('sgr0').decode() self.BOLD = bold.decode() self.UNDER = under.decode() dim = curses.tigetstr('dim') # TODO: more reliable way to get gray color good for both dark and light schemes. self.DIM = dim.decode() if dim else PLAIN_ANSI_DIM self.BLUE = curses.tparm(set_color, curses.COLOR_BLUE).decode() self.GREEN = curses.tparm(set_color, curses.COLOR_GREEN).decode() self.RED = curses.tparm(set_color, curses.COLOR_RED).decode() self.YELLOW = curses.tparm(set_color, curses.COLOR_YELLOW).decode() self.colors = { 'red': self.RED, 'green': self.GREEN, 'blue': self.BLUE, 'yellow': self.YELLOW, 'none': '' }
def __init__(self, buffer=sys.stdout, no_color=False): if not curses: no_color = True if not no_color: no_color = isinstance(sys.stdout, StringIO) or \ not sys.stdout.isatty() self.no_color = no_color # Don't bother initiating color if there's no color. if not no_color: # Get curses all ready to write some stuff to the screen. curses.setupterm() # Initialize a store for the colors and pre-populate it # with the un-color color. self.colors = {"NORMAL": curses.tigetstr("sgr0") or ''} # Determines capabilities of the terminal. fgColorSeq = curses.tigetstr('setaf') or \ curses.tigetstr('setf') or '' # Go through each color and figure out what the sequences # are for each, then store the sequences in the store we # made above. for color in COLORS: colorIndex = getattr(curses, 'COLOR_%s' % color) self.colors[color] = curses.tparm(fgColorSeq, colorIndex) self.buffer = buffer
def __call__(self, *args): try: # Re-encode the cap, because tparm() takes a bytestring in Python # 3. However, appear to be a plain Unicode string otherwise so # concats work. # # We use *latin1* encoding so that bytes emitted by tparm are # encoded to their native value: some terminal kinds, such as # 'avatar' or 'kermit', emit 8-bit bytes in range 0x7f to 0xff. # latin1 leaves these values unmodified in their conversion to # unicode byte values. The terminal emulator will "catch" and # handle these values, even if emitting utf8-encoded text, where # these bytes would otherwise be illegal utf8 start bytes. parametrized = tparm(self.encode('latin1'), *args).decode('latin1') return (parametrized if self._normal is None else FormattingString(parametrized, self._normal)) except curses.error: # Catch "must call (at least) setupterm() first" errors, as when # running simply `nosetests` (without progressive) on nose- # progressive. Perhaps the terminal has gone away between calling # tigetstr and calling tparm. return u'' except TypeError: # If the first non-int (i.e. incorrect) arg was a string, suggest # something intelligent: if len(args) == 1 and isinstance(args[0], basestring): raise TypeError( 'A native or nonexistent capability template received ' '%r when it was expecting ints. You probably misspelled a ' 'formatting call like bright_red_on_white(...).' % args) else: # Somebody passed a non-string; I don't feel confident # guessing what they were trying to do. raise
def get(cap, *args, **kwargs): default = kwargs.pop('default', '') if 'PWNLIB_NOTERM' in os.environ: return '' # Hack for readthedocs.org if 'READTHEDOCS' in os.environ: return '' if kwargs != {}: raise TypeError("get(): No such argument %r" % kwargs.popitem()[0]) if cache == None: init() s = cache.get(cap) if not s: s = curses.tigetstr(cap) if s == None: s = curses.tigetnum(cap) if s == -2: s = curses.tigetflag(cap) if s == -1: # default to empty string so tparm doesn't fail s = '' else: s = bool(s) cache[cap] = s # if `s' is not set `curses.tparm' will throw an error if given arguments if args and s: return curses.tparm(s, *args) else: return s
def csi(self, capname, *args): """Return the escape sequence for the selected Control Sequence.""" value = curses.tigetstr(capname) if value is None: return b'' else: return curses.tparm(value, *args)
def __call__(self, *args): try: # Re-encode the cap, because tparm() takes a bytestring in Python # 3. However, appear to be a plain Unicode string otherwise so # concats work. parametrized = tparm(self.encode('utf-8'), *args).decode('utf-8') return (parametrized if self._normal is None else FormattingString(parametrized, self._normal)) except curses.error: # Catch "must call (at least) setupterm() first" errors, as when # running simply `nosetests` (without progressive) on nose- # progressive. Perhaps the terminal has gone away between calling # tigetstr and calling tparm. return u'' except TypeError: # If the first non-int (i.e. incorrect) arg was a string, suggest # something intelligent: if len(args) == 1 and isinstance(args[0], basestring): raise TypeError( 'A native or nonexistent capability template received ' '%r when it was expecting ints. You probably misspelled a ' 'formatting call like bright_red_on_white(...).' % args) else: # Somebody passed a non-string; I don't feel confident # guessing what they were trying to do. raise
def __init__(self, color=True, fmt=DEFAULT_FORMAT, datefmt=DEFAULT_DATE_FORMAT, colors=DEFAULT_COLORS, precision=3): r""" :arg bool color: Enables color support. :arg string fmt: Log message format. It will be applied to the attributes dict of log records. The text between ``%(color)s`` and ``%(end_color)s`` will be colored depending on the level if color support is on. :arg dict colors: color mappings from logging level to terminal color code :arg string datefmt: Datetime format. Used for formatting ``(asctime)`` placeholder in ``prefix_fmt``. .. versionchanged:: 3.2 Added ``fmt`` and ``datefmt`` arguments. """ super().__init__() self.default_time_format = datefmt self.precision = precision self.default_msec_format = '' self._fmt = fmt self._colors = {} if color and _stderr_supports_color(): fg_color = (curses.tigetstr('setaf') or curses.tigetstr('setf') or '') for levelno, code in colors.items(): self._colors[levelno] = curses.tparm(fg_color, code).decode() self._normal = curses.tigetstr('sgr0').decode() else: self._normal = ''