efro.terminal

Functionality related to terminal IO.

  1# Released under the MIT License. See LICENSE for details.
  2#
  3"""Functionality related to terminal IO."""
  4from __future__ import annotations
  5
  6import sys
  7import os
  8from enum import Enum, unique
  9from typing import TYPE_CHECKING
 10
 11if TYPE_CHECKING:
 12    from typing import Any, ClassVar
 13
 14
 15@unique
 16class TerminalColor(Enum):
 17    """Color codes for printing to terminals.
 18
 19    Generally the Clr class should be used when incorporating color into
 20    terminal output, as it handles non-color-supporting terminals/etc.
 21    """
 22
 23    # Styles
 24    RESET = '\033[0m'
 25    BOLD = '\033[1m'
 26    UNDERLINE = '\033[4m'
 27    INVERSE = '\033[7m'
 28
 29    # Normal foreground colors
 30    BLACK = '\033[30m'
 31    RED = '\033[31m'
 32    GREEN = '\033[32m'
 33    YELLOW = '\033[33m'
 34    BLUE = '\033[34m'
 35    MAGENTA = '\033[35m'
 36    CYAN = '\033[36m'
 37    WHITE = '\033[37m'
 38
 39    # Normal background colors.
 40    BG_BLACK = '\033[40m'
 41    BG_RED = '\033[41m'
 42    BG_GREEN = '\033[42m'
 43    BG_YELLOW = '\033[43m'
 44    BG_BLUE = '\033[44m'
 45    BG_MAGENTA = '\033[45m'
 46    BG_CYAN = '\033[46m'
 47    BG_WHITE = '\033[47m'
 48
 49    # Strong foreground colors
 50    STRONG_BLACK = '\033[90m'
 51    STRONG_RED = '\033[91m'
 52    STRONG_GREEN = '\033[92m'
 53    STRONG_YELLOW = '\033[93m'
 54    STRONG_BLUE = '\033[94m'
 55    STRONG_MAGENTA = '\033[95m'
 56    STRONG_CYAN = '\033[96m'
 57    STRONG_WHITE = '\033[97m'
 58
 59    # Strong background colors.
 60    STRONG_BG_BLACK = '\033[100m'
 61    STRONG_BG_RED = '\033[101m'
 62    STRONG_BG_GREEN = '\033[102m'
 63    STRONG_BG_YELLOW = '\033[103m'
 64    STRONG_BG_BLUE = '\033[104m'
 65    STRONG_BG_MAGENTA = '\033[105m'
 66    STRONG_BG_CYAN = '\033[106m'
 67    STRONG_BG_WHITE = '\033[107m'
 68
 69
 70def _default_color_enabled() -> bool:
 71    """Return whether we enable ANSI color codes by default."""
 72    import platform
 73
 74    # If we're not attached to a terminal, go with no-color.
 75    if not sys.__stdout__.isatty():
 76        return False
 77
 78    # Another common way to say the terminal can't do fancy stuff like color:
 79    if os.environ.get('TERM') == 'dumb':
 80        return False
 81
 82    # On windows, try to enable ANSI color mode.
 83    if platform.system() == 'Windows':
 84        return _windows_enable_color()
 85
 86    # We seem to be a terminal with color support; let's do it!
 87    return True
 88
 89
 90# noinspection PyPep8Naming
 91def _windows_enable_color() -> bool:
 92    """Attempt to enable ANSI color on windows terminal; return success."""
 93    # pylint: disable=invalid-name, import-error, undefined-variable
 94    # Pulled from: https://bugs.python.org/issue30075
 95    import msvcrt
 96    import ctypes
 97    from ctypes import wintypes
 98
 99    kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)  # type: ignore
100
101    ERROR_INVALID_PARAMETER = 0x0057
102    ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
103
104    def _check_bool(result: Any, _func: Any, args: Any) -> Any:
105        if not result:
106            raise ctypes.WinError(ctypes.get_last_error())  # type: ignore
107        return args
108
109    LPDWORD = ctypes.POINTER(wintypes.DWORD)
110    kernel32.GetConsoleMode.errcheck = _check_bool
111    kernel32.GetConsoleMode.argtypes = (wintypes.HANDLE, LPDWORD)
112    kernel32.SetConsoleMode.errcheck = _check_bool
113    kernel32.SetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.DWORD)
114
115    def set_conout_mode(new_mode: int, mask: int = 0xFFFFFFFF) -> int:
116        # don't assume StandardOutput is a console.
117        # open CONOUT$ instead
118        fdout = os.open('CONOUT$', os.O_RDWR)
119        try:
120            hout = msvcrt.get_osfhandle(fdout)  # type: ignore
121            # pylint: disable=useless-suppression
122            # pylint: disable=no-value-for-parameter
123            old_mode = wintypes.DWORD()
124            # pylint: enable=useless-suppression
125            kernel32.GetConsoleMode(hout, ctypes.byref(old_mode))
126            mode = (new_mode & mask) | (old_mode.value & ~mask)
127            kernel32.SetConsoleMode(hout, mode)
128            return old_mode.value
129        finally:
130            os.close(fdout)
131
132    def enable_vt_mode() -> int:
133        mode = mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING
134        try:
135            return set_conout_mode(mode, mask)
136        except WindowsError as exc:  # type: ignore
137            if exc.winerror == ERROR_INVALID_PARAMETER:
138                raise NotImplementedError from exc
139            raise
140
141    try:
142        enable_vt_mode()
143        return True
144    except NotImplementedError:
145        return False
146
147
148class ClrBase:
149    """Base class for color convenience class."""
150
151    RST: ClassVar[str]
152    BLD: ClassVar[str]
153    UND: ClassVar[str]
154    INV: ClassVar[str]
155
156    # Normal foreground colors
157    BLK: ClassVar[str]
158    RED: ClassVar[str]
159    GRN: ClassVar[str]
160    YLW: ClassVar[str]
161    BLU: ClassVar[str]
162    MAG: ClassVar[str]
163    CYN: ClassVar[str]
164    WHT: ClassVar[str]
165
166    # Normal background colors.
167    BBLK: ClassVar[str]
168    BRED: ClassVar[str]
169    BGRN: ClassVar[str]
170    BYLW: ClassVar[str]
171    BBLU: ClassVar[str]
172    BMAG: ClassVar[str]
173    BCYN: ClassVar[str]
174    BWHT: ClassVar[str]
175
176    # Strong foreground colors
177    SBLK: ClassVar[str]
178    SRED: ClassVar[str]
179    SGRN: ClassVar[str]
180    SYLW: ClassVar[str]
181    SBLU: ClassVar[str]
182    SMAG: ClassVar[str]
183    SCYN: ClassVar[str]
184    SWHT: ClassVar[str]
185
186    # Strong background colors.
187    SBBLK: ClassVar[str]
188    SBRED: ClassVar[str]
189    SBGRN: ClassVar[str]
190    SBYLW: ClassVar[str]
191    SBBLU: ClassVar[str]
192    SBMAG: ClassVar[str]
193    SBCYN: ClassVar[str]
194    SBWHT: ClassVar[str]
195
196
197class ClrAlways(ClrBase):
198    """Convenience class for color terminal output.
199
200    This version has colors always enabled. Generally you should use Clr which
201    points to the correct enabled/disabled class depending on the environment.
202    """
203
204    color_enabled = True
205
206    # Styles
207    RST = TerminalColor.RESET.value
208    BLD = TerminalColor.BOLD.value
209    UND = TerminalColor.UNDERLINE.value
210    INV = TerminalColor.INVERSE.value
211
212    # Normal foreground colors
213    BLK = TerminalColor.BLACK.value
214    RED = TerminalColor.RED.value
215    GRN = TerminalColor.GREEN.value
216    YLW = TerminalColor.YELLOW.value
217    BLU = TerminalColor.BLUE.value
218    MAG = TerminalColor.MAGENTA.value
219    CYN = TerminalColor.CYAN.value
220    WHT = TerminalColor.WHITE.value
221
222    # Normal background colors.
223    BBLK = TerminalColor.BG_BLACK.value
224    BRED = TerminalColor.BG_RED.value
225    BGRN = TerminalColor.BG_GREEN.value
226    BYLW = TerminalColor.BG_YELLOW.value
227    BBLU = TerminalColor.BG_BLUE.value
228    BMAG = TerminalColor.BG_MAGENTA.value
229    BCYN = TerminalColor.BG_CYAN.value
230    BWHT = TerminalColor.BG_WHITE.value
231
232    # Strong foreground colors
233    SBLK = TerminalColor.STRONG_BLACK.value
234    SRED = TerminalColor.STRONG_RED.value
235    SGRN = TerminalColor.STRONG_GREEN.value
236    SYLW = TerminalColor.STRONG_YELLOW.value
237    SBLU = TerminalColor.STRONG_BLUE.value
238    SMAG = TerminalColor.STRONG_MAGENTA.value
239    SCYN = TerminalColor.STRONG_CYAN.value
240    SWHT = TerminalColor.STRONG_WHITE.value
241
242    # Strong background colors.
243    SBBLK = TerminalColor.STRONG_BG_BLACK.value
244    SBRED = TerminalColor.STRONG_BG_RED.value
245    SBGRN = TerminalColor.STRONG_BG_GREEN.value
246    SBYLW = TerminalColor.STRONG_BG_YELLOW.value
247    SBBLU = TerminalColor.STRONG_BG_BLUE.value
248    SBMAG = TerminalColor.STRONG_BG_MAGENTA.value
249    SBCYN = TerminalColor.STRONG_BG_CYAN.value
250    SBWHT = TerminalColor.STRONG_BG_WHITE.value
251
252
253class ClrNever(ClrBase):
254    """Convenience class for color terminal output.
255
256    This version has colors disabled. Generally you should use Clr which
257    points to the correct enabled/disabled class depending on the environment.
258    """
259
260    color_enabled = False
261
262    # Styles
263    RST = ''
264    BLD = ''
265    UND = ''
266    INV = ''
267
268    # Normal foreground colors
269    BLK = ''
270    RED = ''
271    GRN = ''
272    YLW = ''
273    BLU = ''
274    MAG = ''
275    CYN = ''
276    WHT = ''
277
278    # Normal background colors.
279    BBLK = ''
280    BRED = ''
281    BGRN = ''
282    BYLW = ''
283    BBLU = ''
284    BMAG = ''
285    BCYN = ''
286    BWHT = ''
287
288    # Strong foreground colors
289    SBLK = ''
290    SRED = ''
291    SGRN = ''
292    SYLW = ''
293    SBLU = ''
294    SMAG = ''
295    SCYN = ''
296    SWHT = ''
297
298    # Strong background colors.
299    SBBLK = ''
300    SBRED = ''
301    SBGRN = ''
302    SBYLW = ''
303    SBBLU = ''
304    SBMAG = ''
305    SBCYN = ''
306    SBWHT = ''
307
308
309_envval = os.environ.get('EFRO_TERMCOLORS')
310color_enabled: bool = (
311    True
312    if _envval == '1'
313    else False
314    if _envval == '0'
315    else _default_color_enabled()
316)
317Clr: type[ClrBase] = ClrAlways if color_enabled else ClrNever
@unique
class TerminalColor(enum.Enum):
16@unique
17class TerminalColor(Enum):
18    """Color codes for printing to terminals.
19
20    Generally the Clr class should be used when incorporating color into
21    terminal output, as it handles non-color-supporting terminals/etc.
22    """
23
24    # Styles
25    RESET = '\033[0m'
26    BOLD = '\033[1m'
27    UNDERLINE = '\033[4m'
28    INVERSE = '\033[7m'
29
30    # Normal foreground colors
31    BLACK = '\033[30m'
32    RED = '\033[31m'
33    GREEN = '\033[32m'
34    YELLOW = '\033[33m'
35    BLUE = '\033[34m'
36    MAGENTA = '\033[35m'
37    CYAN = '\033[36m'
38    WHITE = '\033[37m'
39
40    # Normal background colors.
41    BG_BLACK = '\033[40m'
42    BG_RED = '\033[41m'
43    BG_GREEN = '\033[42m'
44    BG_YELLOW = '\033[43m'
45    BG_BLUE = '\033[44m'
46    BG_MAGENTA = '\033[45m'
47    BG_CYAN = '\033[46m'
48    BG_WHITE = '\033[47m'
49
50    # Strong foreground colors
51    STRONG_BLACK = '\033[90m'
52    STRONG_RED = '\033[91m'
53    STRONG_GREEN = '\033[92m'
54    STRONG_YELLOW = '\033[93m'
55    STRONG_BLUE = '\033[94m'
56    STRONG_MAGENTA = '\033[95m'
57    STRONG_CYAN = '\033[96m'
58    STRONG_WHITE = '\033[97m'
59
60    # Strong background colors.
61    STRONG_BG_BLACK = '\033[100m'
62    STRONG_BG_RED = '\033[101m'
63    STRONG_BG_GREEN = '\033[102m'
64    STRONG_BG_YELLOW = '\033[103m'
65    STRONG_BG_BLUE = '\033[104m'
66    STRONG_BG_MAGENTA = '\033[105m'
67    STRONG_BG_CYAN = '\033[106m'
68    STRONG_BG_WHITE = '\033[107m'

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.

RESET = <TerminalColor.RESET: '\x1b[0m'>
BOLD = <TerminalColor.BOLD: '\x1b[1m'>
UNDERLINE = <TerminalColor.UNDERLINE: '\x1b[4m'>
INVERSE = <TerminalColor.INVERSE: '\x1b[7m'>
BLACK = <TerminalColor.BLACK: '\x1b[30m'>
RED = <TerminalColor.RED: '\x1b[31m'>
GREEN = <TerminalColor.GREEN: '\x1b[32m'>
YELLOW = <TerminalColor.YELLOW: '\x1b[33m'>
BLUE = <TerminalColor.BLUE: '\x1b[34m'>
MAGENTA = <TerminalColor.MAGENTA: '\x1b[35m'>
CYAN = <TerminalColor.CYAN: '\x1b[36m'>
WHITE = <TerminalColor.WHITE: '\x1b[37m'>
BG_BLACK = <TerminalColor.BG_BLACK: '\x1b[40m'>
BG_RED = <TerminalColor.BG_RED: '\x1b[41m'>
BG_GREEN = <TerminalColor.BG_GREEN: '\x1b[42m'>
BG_YELLOW = <TerminalColor.BG_YELLOW: '\x1b[43m'>
BG_BLUE = <TerminalColor.BG_BLUE: '\x1b[44m'>
BG_MAGENTA = <TerminalColor.BG_MAGENTA: '\x1b[45m'>
BG_CYAN = <TerminalColor.BG_CYAN: '\x1b[46m'>
BG_WHITE = <TerminalColor.BG_WHITE: '\x1b[47m'>
STRONG_BLACK = <TerminalColor.STRONG_BLACK: '\x1b[90m'>
STRONG_RED = <TerminalColor.STRONG_RED: '\x1b[91m'>
STRONG_GREEN = <TerminalColor.STRONG_GREEN: '\x1b[92m'>
STRONG_YELLOW = <TerminalColor.STRONG_YELLOW: '\x1b[93m'>
STRONG_BLUE = <TerminalColor.STRONG_BLUE: '\x1b[94m'>
STRONG_MAGENTA = <TerminalColor.STRONG_MAGENTA: '\x1b[95m'>
STRONG_CYAN = <TerminalColor.STRONG_CYAN: '\x1b[96m'>
STRONG_WHITE = <TerminalColor.STRONG_WHITE: '\x1b[97m'>
STRONG_BG_BLACK = <TerminalColor.STRONG_BG_BLACK: '\x1b[100m'>
STRONG_BG_RED = <TerminalColor.STRONG_BG_RED: '\x1b[101m'>
STRONG_BG_GREEN = <TerminalColor.STRONG_BG_GREEN: '\x1b[102m'>
STRONG_BG_YELLOW = <TerminalColor.STRONG_BG_YELLOW: '\x1b[103m'>
STRONG_BG_BLUE = <TerminalColor.STRONG_BG_BLUE: '\x1b[104m'>
STRONG_BG_MAGENTA = <TerminalColor.STRONG_BG_MAGENTA: '\x1b[105m'>
STRONG_BG_CYAN = <TerminalColor.STRONG_BG_CYAN: '\x1b[106m'>
STRONG_BG_WHITE = <TerminalColor.STRONG_BG_WHITE: '\x1b[107m'>
Inherited Members
enum.Enum
name
value
class ClrBase:
149class ClrBase:
150    """Base class for color convenience class."""
151
152    RST: ClassVar[str]
153    BLD: ClassVar[str]
154    UND: ClassVar[str]
155    INV: ClassVar[str]
156
157    # Normal foreground colors
158    BLK: ClassVar[str]
159    RED: ClassVar[str]
160    GRN: ClassVar[str]
161    YLW: ClassVar[str]
162    BLU: ClassVar[str]
163    MAG: ClassVar[str]
164    CYN: ClassVar[str]
165    WHT: ClassVar[str]
166
167    # Normal background colors.
168    BBLK: ClassVar[str]
169    BRED: ClassVar[str]
170    BGRN: ClassVar[str]
171    BYLW: ClassVar[str]
172    BBLU: ClassVar[str]
173    BMAG: ClassVar[str]
174    BCYN: ClassVar[str]
175    BWHT: ClassVar[str]
176
177    # Strong foreground colors
178    SBLK: ClassVar[str]
179    SRED: ClassVar[str]
180    SGRN: ClassVar[str]
181    SYLW: ClassVar[str]
182    SBLU: ClassVar[str]
183    SMAG: ClassVar[str]
184    SCYN: ClassVar[str]
185    SWHT: ClassVar[str]
186
187    # Strong background colors.
188    SBBLK: ClassVar[str]
189    SBRED: ClassVar[str]
190    SBGRN: ClassVar[str]
191    SBYLW: ClassVar[str]
192    SBBLU: ClassVar[str]
193    SBMAG: ClassVar[str]
194    SBCYN: ClassVar[str]
195    SBWHT: ClassVar[str]

Base class for color convenience class.

RST: ClassVar[str]
BLD: ClassVar[str]
UND: ClassVar[str]
INV: ClassVar[str]
BLK: ClassVar[str]
RED: ClassVar[str]
GRN: ClassVar[str]
YLW: ClassVar[str]
BLU: ClassVar[str]
MAG: ClassVar[str]
CYN: ClassVar[str]
WHT: ClassVar[str]
BBLK: ClassVar[str]
BRED: ClassVar[str]
BGRN: ClassVar[str]
BYLW: ClassVar[str]
BBLU: ClassVar[str]
BMAG: ClassVar[str]
BCYN: ClassVar[str]
BWHT: ClassVar[str]
SBLK: ClassVar[str]
SRED: ClassVar[str]
SGRN: ClassVar[str]
SYLW: ClassVar[str]
SBLU: ClassVar[str]
SMAG: ClassVar[str]
SCYN: ClassVar[str]
SWHT: ClassVar[str]
SBBLK: ClassVar[str]
SBRED: ClassVar[str]
SBGRN: ClassVar[str]
SBYLW: ClassVar[str]
SBBLU: ClassVar[str]
SBMAG: ClassVar[str]
SBCYN: ClassVar[str]
SBWHT: ClassVar[str]
class ClrAlways(ClrBase):
198class ClrAlways(ClrBase):
199    """Convenience class for color terminal output.
200
201    This version has colors always enabled. Generally you should use Clr which
202    points to the correct enabled/disabled class depending on the environment.
203    """
204
205    color_enabled = True
206
207    # Styles
208    RST = TerminalColor.RESET.value
209    BLD = TerminalColor.BOLD.value
210    UND = TerminalColor.UNDERLINE.value
211    INV = TerminalColor.INVERSE.value
212
213    # Normal foreground colors
214    BLK = TerminalColor.BLACK.value
215    RED = TerminalColor.RED.value
216    GRN = TerminalColor.GREEN.value
217    YLW = TerminalColor.YELLOW.value
218    BLU = TerminalColor.BLUE.value
219    MAG = TerminalColor.MAGENTA.value
220    CYN = TerminalColor.CYAN.value
221    WHT = TerminalColor.WHITE.value
222
223    # Normal background colors.
224    BBLK = TerminalColor.BG_BLACK.value
225    BRED = TerminalColor.BG_RED.value
226    BGRN = TerminalColor.BG_GREEN.value
227    BYLW = TerminalColor.BG_YELLOW.value
228    BBLU = TerminalColor.BG_BLUE.value
229    BMAG = TerminalColor.BG_MAGENTA.value
230    BCYN = TerminalColor.BG_CYAN.value
231    BWHT = TerminalColor.BG_WHITE.value
232
233    # Strong foreground colors
234    SBLK = TerminalColor.STRONG_BLACK.value
235    SRED = TerminalColor.STRONG_RED.value
236    SGRN = TerminalColor.STRONG_GREEN.value
237    SYLW = TerminalColor.STRONG_YELLOW.value
238    SBLU = TerminalColor.STRONG_BLUE.value
239    SMAG = TerminalColor.STRONG_MAGENTA.value
240    SCYN = TerminalColor.STRONG_CYAN.value
241    SWHT = TerminalColor.STRONG_WHITE.value
242
243    # Strong background colors.
244    SBBLK = TerminalColor.STRONG_BG_BLACK.value
245    SBRED = TerminalColor.STRONG_BG_RED.value
246    SBGRN = TerminalColor.STRONG_BG_GREEN.value
247    SBYLW = TerminalColor.STRONG_BG_YELLOW.value
248    SBBLU = TerminalColor.STRONG_BG_BLUE.value
249    SBMAG = TerminalColor.STRONG_BG_MAGENTA.value
250    SBCYN = TerminalColor.STRONG_BG_CYAN.value
251    SBWHT = TerminalColor.STRONG_BG_WHITE.value

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
RST = '\x1b[0m'
BLD = '\x1b[1m'
UND = '\x1b[4m'
INV = '\x1b[7m'
BLK = '\x1b[30m'
RED = '\x1b[31m'
GRN = '\x1b[32m'
YLW = '\x1b[33m'
BLU = '\x1b[34m'
MAG = '\x1b[35m'
CYN = '\x1b[36m'
WHT = '\x1b[37m'
BBLK = '\x1b[40m'
BRED = '\x1b[41m'
BGRN = '\x1b[42m'
BYLW = '\x1b[43m'
BBLU = '\x1b[44m'
BMAG = '\x1b[45m'
BCYN = '\x1b[46m'
BWHT = '\x1b[47m'
SBLK = '\x1b[90m'
SRED = '\x1b[91m'
SGRN = '\x1b[92m'
SYLW = '\x1b[93m'
SBLU = '\x1b[94m'
SMAG = '\x1b[95m'
SCYN = '\x1b[96m'
SWHT = '\x1b[97m'
SBBLK = '\x1b[100m'
SBRED = '\x1b[101m'
SBGRN = '\x1b[102m'
SBYLW = '\x1b[103m'
SBBLU = '\x1b[104m'
SBMAG = '\x1b[105m'
SBCYN = '\x1b[106m'
SBWHT = '\x1b[107m'
class ClrNever(ClrBase):
254class ClrNever(ClrBase):
255    """Convenience class for color terminal output.
256
257    This version has colors disabled. Generally you should use Clr which
258    points to the correct enabled/disabled class depending on the environment.
259    """
260
261    color_enabled = False
262
263    # Styles
264    RST = ''
265    BLD = ''
266    UND = ''
267    INV = ''
268
269    # Normal foreground colors
270    BLK = ''
271    RED = ''
272    GRN = ''
273    YLW = ''
274    BLU = ''
275    MAG = ''
276    CYN = ''
277    WHT = ''
278
279    # Normal background colors.
280    BBLK = ''
281    BRED = ''
282    BGRN = ''
283    BYLW = ''
284    BBLU = ''
285    BMAG = ''
286    BCYN = ''
287    BWHT = ''
288
289    # Strong foreground colors
290    SBLK = ''
291    SRED = ''
292    SGRN = ''
293    SYLW = ''
294    SBLU = ''
295    SMAG = ''
296    SCYN = ''
297    SWHT = ''
298
299    # Strong background colors.
300    SBBLK = ''
301    SBRED = ''
302    SBGRN = ''
303    SBYLW = ''
304    SBBLU = ''
305    SBMAG = ''
306    SBCYN = ''
307    SBWHT = ''

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
RST = ''
BLD = ''
UND = ''
INV = ''
BLK = ''
RED = ''
GRN = ''
YLW = ''
BLU = ''
MAG = ''
CYN = ''
WHT = ''
BBLK = ''
BRED = ''
BGRN = ''
BYLW = ''
BBLU = ''
BMAG = ''
BCYN = ''
BWHT = ''
SBLK = ''
SRED = ''
SGRN = ''
SYLW = ''
SBLU = ''
SMAG = ''
SCYN = ''
SWHT = ''
SBBLK = ''
SBRED = ''
SBGRN = ''
SBYLW = ''
SBBLU = ''
SBMAG = ''
SBCYN = ''
SBWHT = ''
color_enabled: bool = False
Clr: type[ClrBase] = <class 'ClrNever'>