# Released under the MIT License. See LICENSE for details.#"""Functionality related to terminal IO."""from__future__importannotationsimportsysimportosfromenumimportEnum,uniquefromtypingimportTYPE_CHECKINGifTYPE_CHECKING:fromtypingimportAny,ClassVar
[docs]@uniqueclassTerminalColor(Enum):"""Color codes for printing to terminals. Generally the Clr class should be used when incorporating color into terminal output, as it handles non-color-supporting terminals/etc. """# StylesRESET='\033[0m'BOLD='\033[1m'UNDERLINE='\033[4m'INVERSE='\033[7m'# Normal foreground colorsBLACK='\033[30m'RED='\033[31m'GREEN='\033[32m'YELLOW='\033[33m'BLUE='\033[34m'MAGENTA='\033[35m'CYAN='\033[36m'WHITE='\033[37m'# Normal background colors.BG_BLACK='\033[40m'BG_RED='\033[41m'BG_GREEN='\033[42m'BG_YELLOW='\033[43m'BG_BLUE='\033[44m'BG_MAGENTA='\033[45m'BG_CYAN='\033[46m'BG_WHITE='\033[47m'# Strong foreground colorsSTRONG_BLACK='\033[90m'STRONG_RED='\033[91m'STRONG_GREEN='\033[92m'STRONG_YELLOW='\033[93m'STRONG_BLUE='\033[94m'STRONG_MAGENTA='\033[95m'STRONG_CYAN='\033[96m'STRONG_WHITE='\033[97m'# Strong background colors.STRONG_BG_BLACK='\033[100m'STRONG_BG_RED='\033[101m'STRONG_BG_GREEN='\033[102m'STRONG_BG_YELLOW='\033[103m'STRONG_BG_BLUE='\033[104m'STRONG_BG_MAGENTA='\033[105m'STRONG_BG_CYAN='\033[106m'STRONG_BG_WHITE='\033[107m'
def_default_color_enabled()->bool:"""Return whether we enable ANSI color codes by default."""importplatform# If our stdout is not attached to a terminal, go with no-color.assertsys.__stdout__isnotNoneifnotsys.__stdout__.isatty():returnFalsetermenv=os.environ.get('TERM')# If TERM is unset, don't attempt color (this is currently the case# in xcode).iftermenvisNone:returnFalse# A common way to say the terminal can't do fancy stuff like color.iftermenv=='dumb':returnFalse# On windows, try to enable ANSI color mode.ifplatform.system()=='Windows':return_windows_enable_color()# We seem to be a terminal with color support; let's do it!returnTrue# noinspection PyPep8Namingdef_windows_enable_color()->bool:"""Attempt to enable ANSI color on windows terminal; return success."""# pylint: disable=invalid-name, import-error, undefined-variable# Pulled from: https://bugs.python.org/issue30075importmsvcrtimportctypesfromctypesimportwintypeskernel32=ctypes.WinDLL('kernel32',use_last_error=True)# type: ignoreERROR_INVALID_PARAMETER=0x0057ENABLE_VIRTUAL_TERMINAL_PROCESSING=0x0004def_check_bool(result:Any,_func:Any,args:Any)->Any:ifnotresult:raisectypes.WinError(ctypes.get_last_error())# type: ignorereturnargsLPDWORD=ctypes.POINTER(wintypes.DWORD)kernel32.GetConsoleMode.errcheck=_check_boolkernel32.GetConsoleMode.argtypes=(wintypes.HANDLE,LPDWORD)kernel32.SetConsoleMode.errcheck=_check_boolkernel32.SetConsoleMode.argtypes=(wintypes.HANDLE,wintypes.DWORD)defset_conout_mode(new_mode:int,mask:int=0xFFFFFFFF)->int:# don't assume StandardOutput is a console.# open CONOUT$ insteadfdout=os.open('CONOUT$',os.O_RDWR)try:hout=msvcrt.get_osfhandle(fdout)# type: ignore# pylint: disable=useless-suppression# pylint: disable=no-value-for-parameterold_mode=wintypes.DWORD()# pylint: enable=useless-suppressionkernel32.GetConsoleMode(hout,ctypes.byref(old_mode))mode=(new_mode&mask)|(old_mode.value&~mask)kernel32.SetConsoleMode(hout,mode)returnold_mode.valuefinally:os.close(fdout)defenable_vt_mode()->int:mode=mask=ENABLE_VIRTUAL_TERMINAL_PROCESSINGtry:returnset_conout_mode(mode,mask)exceptWindowsErrorasexc:# type: ignoreifexc.winerror==ERROR_INVALID_PARAMETER:raiseNotImplementedErrorfromexcraisetry:enable_vt_mode()returnTrueexceptNotImplementedError:returnFalse
[docs]classClrBase:"""Base class for color convenience class."""RST:ClassVar[str]BLD:ClassVar[str]UND:ClassVar[str]INV:ClassVar[str]# Normal foreground colorsBLK:ClassVar[str]RED:ClassVar[str]GRN:ClassVar[str]YLW:ClassVar[str]BLU:ClassVar[str]MAG:ClassVar[str]CYN:ClassVar[str]WHT:ClassVar[str]# Normal background colors.BBLK:ClassVar[str]BRED:ClassVar[str]BGRN:ClassVar[str]BYLW:ClassVar[str]BBLU:ClassVar[str]BMAG:ClassVar[str]BCYN:ClassVar[str]BWHT:ClassVar[str]# Strong foreground colorsSBLK:ClassVar[str]SRED:ClassVar[str]SGRN:ClassVar[str]SYLW:ClassVar[str]SBLU:ClassVar[str]SMAG:ClassVar[str]SCYN:ClassVar[str]SWHT:ClassVar[str]# Strong background colors.SBBLK:ClassVar[str]SBRED:ClassVar[str]SBGRN:ClassVar[str]SBYLW:ClassVar[str]SBBLU:ClassVar[str]SBMAG:ClassVar[str]SBCYN:ClassVar[str]SBWHT:ClassVar[str]
[docs]classClrAlways(ClrBase):"""Convenience class for color terminal output. This version has colors always enabled. Generally you should use Clr which points to the correct enabled/disabled class depending on the environment. """color_enabled=True# StylesRST=TerminalColor.RESET.valueBLD=TerminalColor.BOLD.valueUND=TerminalColor.UNDERLINE.valueINV=TerminalColor.INVERSE.value# Normal foreground colorsBLK=TerminalColor.BLACK.valueRED=TerminalColor.RED.valueGRN=TerminalColor.GREEN.valueYLW=TerminalColor.YELLOW.valueBLU=TerminalColor.BLUE.valueMAG=TerminalColor.MAGENTA.valueCYN=TerminalColor.CYAN.valueWHT=TerminalColor.WHITE.value# Normal background colors.BBLK=TerminalColor.BG_BLACK.valueBRED=TerminalColor.BG_RED.valueBGRN=TerminalColor.BG_GREEN.valueBYLW=TerminalColor.BG_YELLOW.valueBBLU=TerminalColor.BG_BLUE.valueBMAG=TerminalColor.BG_MAGENTA.valueBCYN=TerminalColor.BG_CYAN.valueBWHT=TerminalColor.BG_WHITE.value# Strong foreground colorsSBLK=TerminalColor.STRONG_BLACK.valueSRED=TerminalColor.STRONG_RED.valueSGRN=TerminalColor.STRONG_GREEN.valueSYLW=TerminalColor.STRONG_YELLOW.valueSBLU=TerminalColor.STRONG_BLUE.valueSMAG=TerminalColor.STRONG_MAGENTA.valueSCYN=TerminalColor.STRONG_CYAN.valueSWHT=TerminalColor.STRONG_WHITE.value# Strong background colors.SBBLK=TerminalColor.STRONG_BG_BLACK.valueSBRED=TerminalColor.STRONG_BG_RED.valueSBGRN=TerminalColor.STRONG_BG_GREEN.valueSBYLW=TerminalColor.STRONG_BG_YELLOW.valueSBBLU=TerminalColor.STRONG_BG_BLUE.valueSBMAG=TerminalColor.STRONG_BG_MAGENTA.valueSBCYN=TerminalColor.STRONG_BG_CYAN.valueSBWHT=TerminalColor.STRONG_BG_WHITE.value
[docs]classClrNever(ClrBase):"""Convenience class for color terminal output. This version has colors disabled. Generally you should use Clr which points to the correct enabled/disabled class depending on the environment. """color_enabled=False# StylesRST=''BLD=''UND=''INV=''# Normal foreground colorsBLK=''RED=''GRN=''YLW=''BLU=''MAG=''CYN=''WHT=''# Normal background colors.BBLK=''BRED=''BGRN=''BYLW=''BBLU=''BMAG=''BCYN=''BWHT=''# Strong foreground colorsSBLK=''SRED=''SGRN=''SYLW=''SBLU=''SMAG=''SCYN=''SWHT=''# Strong background colors.SBBLK=''SBRED=''SBGRN=''SBYLW=''SBBLU=''SBMAG=''SBCYN=''SBWHT=''