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 our stdout is not attached to a terminal, go with no-color.
 75    assert sys.__stdout__ is not None
 76    if not sys.__stdout__.isatty():
 77        return False
 78
 79    termenv = os.environ.get('TERM')
 80
 81    # If TERM is unset, don't attempt color (this is currently the case
 82    # in xcode).
 83    if termenv is None:
 84        return False
 85
 86    # A common way to say the terminal can't do fancy stuff like color.
 87    if termenv == 'dumb':
 88        return False
 89
 90    # On windows, try to enable ANSI color mode.
 91    if platform.system() == 'Windows':
 92        return _windows_enable_color()
 93
 94    # We seem to be a terminal with color support; let's do it!
 95    return True
 96
 97
 98# noinspection PyPep8Naming
 99def _windows_enable_color() -> bool:
100    """Attempt to enable ANSI color on windows terminal; return success."""
101    # pylint: disable=invalid-name, import-error, undefined-variable
102    # Pulled from: https://bugs.python.org/issue30075
103    import msvcrt
104    import ctypes
105    from ctypes import wintypes
106
107    kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)  # type: ignore
108
109    ERROR_INVALID_PARAMETER = 0x0057
110    ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
111
112    def _check_bool(result: Any, _func: Any, args: Any) -> Any:
113        if not result:
114            raise ctypes.WinError(ctypes.get_last_error())  # type: ignore
115        return args
116
117    LPDWORD = ctypes.POINTER(wintypes.DWORD)
118    kernel32.GetConsoleMode.errcheck = _check_bool
119    kernel32.GetConsoleMode.argtypes = (wintypes.HANDLE, LPDWORD)
120    kernel32.SetConsoleMode.errcheck = _check_bool
121    kernel32.SetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.DWORD)
122
123    def set_conout_mode(new_mode: int, mask: int = 0xFFFFFFFF) -> int:
124        # don't assume StandardOutput is a console.
125        # open CONOUT$ instead
126        fdout = os.open('CONOUT$', os.O_RDWR)
127        try:
128            hout = msvcrt.get_osfhandle(fdout)  # type: ignore
129            # pylint: disable=useless-suppression
130            # pylint: disable=no-value-for-parameter
131            old_mode = wintypes.DWORD()
132            # pylint: enable=useless-suppression
133            kernel32.GetConsoleMode(hout, ctypes.byref(old_mode))
134            mode = (new_mode & mask) | (old_mode.value & ~mask)
135            kernel32.SetConsoleMode(hout, mode)
136            return old_mode.value
137        finally:
138            os.close(fdout)
139
140    def enable_vt_mode() -> int:
141        mode = mask = ENABLE_VIRTUAL_TERMINAL_PROCESSING
142        try:
143            return set_conout_mode(mode, mask)
144        except WindowsError as exc:  # type: ignore
145            if exc.winerror == ERROR_INVALID_PARAMETER:
146                raise NotImplementedError from exc
147            raise
148
149    try:
150        enable_vt_mode()
151        return True
152    except NotImplementedError:
153        return False
154
155
156class ClrBase:
157    """Base class for color convenience class."""
158
159    RST: ClassVar[str]
160    BLD: ClassVar[str]
161    UND: ClassVar[str]
162    INV: ClassVar[str]
163
164    # Normal foreground colors
165    BLK: ClassVar[str]
166    RED: ClassVar[str]
167    GRN: ClassVar[str]
168    YLW: ClassVar[str]
169    BLU: ClassVar[str]
170    MAG: ClassVar[str]
171    CYN: ClassVar[str]
172    WHT: ClassVar[str]
173
174    # Normal background colors.
175    BBLK: ClassVar[str]
176    BRED: ClassVar[str]
177    BGRN: ClassVar[str]
178    BYLW: ClassVar[str]
179    BBLU: ClassVar[str]
180    BMAG: ClassVar[str]
181    BCYN: ClassVar[str]
182    BWHT: ClassVar[str]
183
184    # Strong foreground colors
185    SBLK: ClassVar[str]
186    SRED: ClassVar[str]
187    SGRN: ClassVar[str]
188    SYLW: ClassVar[str]
189    SBLU: ClassVar[str]
190    SMAG: ClassVar[str]
191    SCYN: ClassVar[str]
192    SWHT: ClassVar[str]
193
194    # Strong background colors.
195    SBBLK: ClassVar[str]
196    SBRED: ClassVar[str]
197    SBGRN: ClassVar[str]
198    SBYLW: ClassVar[str]
199    SBBLU: ClassVar[str]
200    SBMAG: ClassVar[str]
201    SBCYN: ClassVar[str]
202    SBWHT: ClassVar[str]
203
204
205class ClrAlways(ClrBase):
206    """Convenience class for color terminal output.
207
208    This version has colors always enabled. Generally you should use Clr which
209    points to the correct enabled/disabled class depending on the environment.
210    """
211
212    color_enabled = True
213
214    # Styles
215    RST = TerminalColor.RESET.value
216    BLD = TerminalColor.BOLD.value
217    UND = TerminalColor.UNDERLINE.value
218    INV = TerminalColor.INVERSE.value
219
220    # Normal foreground colors
221    BLK = TerminalColor.BLACK.value
222    RED = TerminalColor.RED.value
223    GRN = TerminalColor.GREEN.value
224    YLW = TerminalColor.YELLOW.value
225    BLU = TerminalColor.BLUE.value
226    MAG = TerminalColor.MAGENTA.value
227    CYN = TerminalColor.CYAN.value
228    WHT = TerminalColor.WHITE.value
229
230    # Normal background colors.
231    BBLK = TerminalColor.BG_BLACK.value
232    BRED = TerminalColor.BG_RED.value
233    BGRN = TerminalColor.BG_GREEN.value
234    BYLW = TerminalColor.BG_YELLOW.value
235    BBLU = TerminalColor.BG_BLUE.value
236    BMAG = TerminalColor.BG_MAGENTA.value
237    BCYN = TerminalColor.BG_CYAN.value
238    BWHT = TerminalColor.BG_WHITE.value
239
240    # Strong foreground colors
241    SBLK = TerminalColor.STRONG_BLACK.value
242    SRED = TerminalColor.STRONG_RED.value
243    SGRN = TerminalColor.STRONG_GREEN.value
244    SYLW = TerminalColor.STRONG_YELLOW.value
245    SBLU = TerminalColor.STRONG_BLUE.value
246    SMAG = TerminalColor.STRONG_MAGENTA.value
247    SCYN = TerminalColor.STRONG_CYAN.value
248    SWHT = TerminalColor.STRONG_WHITE.value
249
250    # Strong background colors.
251    SBBLK = TerminalColor.STRONG_BG_BLACK.value
252    SBRED = TerminalColor.STRONG_BG_RED.value
253    SBGRN = TerminalColor.STRONG_BG_GREEN.value
254    SBYLW = TerminalColor.STRONG_BG_YELLOW.value
255    SBBLU = TerminalColor.STRONG_BG_BLUE.value
256    SBMAG = TerminalColor.STRONG_BG_MAGENTA.value
257    SBCYN = TerminalColor.STRONG_BG_CYAN.value
258    SBWHT = TerminalColor.STRONG_BG_WHITE.value
259
260
261class ClrNever(ClrBase):
262    """Convenience class for color terminal output.
263
264    This version has colors disabled. Generally you should use Clr which
265    points to the correct enabled/disabled class depending on the environment.
266    """
267
268    color_enabled = False
269
270    # Styles
271    RST = ''
272    BLD = ''
273    UND = ''
274    INV = ''
275
276    # Normal foreground colors
277    BLK = ''
278    RED = ''
279    GRN = ''
280    YLW = ''
281    BLU = ''
282    MAG = ''
283    CYN = ''
284    WHT = ''
285
286    # Normal background colors.
287    BBLK = ''
288    BRED = ''
289    BGRN = ''
290    BYLW = ''
291    BBLU = ''
292    BMAG = ''
293    BCYN = ''
294    BWHT = ''
295
296    # Strong foreground colors
297    SBLK = ''
298    SRED = ''
299    SGRN = ''
300    SYLW = ''
301    SBLU = ''
302    SMAG = ''
303    SCYN = ''
304    SWHT = ''
305
306    # Strong background colors.
307    SBBLK = ''
308    SBRED = ''
309    SBGRN = ''
310    SBYLW = ''
311    SBBLU = ''
312    SBMAG = ''
313    SBCYN = ''
314    SBWHT = ''
315
316
317_envval = os.environ.get('EFRO_TERMCOLORS')
318color_enabled: bool = (
319    True
320    if _envval == '1'
321    else False if _envval == '0' else _default_color_enabled()
322)
323Clr: 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:
157class ClrBase:
158    """Base class for color convenience class."""
159
160    RST: ClassVar[str]
161    BLD: ClassVar[str]
162    UND: ClassVar[str]
163    INV: ClassVar[str]
164
165    # Normal foreground colors
166    BLK: ClassVar[str]
167    RED: ClassVar[str]
168    GRN: ClassVar[str]
169    YLW: ClassVar[str]
170    BLU: ClassVar[str]
171    MAG: ClassVar[str]
172    CYN: ClassVar[str]
173    WHT: ClassVar[str]
174
175    # Normal background colors.
176    BBLK: ClassVar[str]
177    BRED: ClassVar[str]
178    BGRN: ClassVar[str]
179    BYLW: ClassVar[str]
180    BBLU: ClassVar[str]
181    BMAG: ClassVar[str]
182    BCYN: ClassVar[str]
183    BWHT: ClassVar[str]
184
185    # Strong foreground colors
186    SBLK: ClassVar[str]
187    SRED: ClassVar[str]
188    SGRN: ClassVar[str]
189    SYLW: ClassVar[str]
190    SBLU: ClassVar[str]
191    SMAG: ClassVar[str]
192    SCYN: ClassVar[str]
193    SWHT: ClassVar[str]
194
195    # Strong background colors.
196    SBBLK: ClassVar[str]
197    SBRED: ClassVar[str]
198    SBGRN: ClassVar[str]
199    SBYLW: ClassVar[str]
200    SBBLU: ClassVar[str]
201    SBMAG: ClassVar[str]
202    SBCYN: ClassVar[str]
203    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):
206class ClrAlways(ClrBase):
207    """Convenience class for color terminal output.
208
209    This version has colors always enabled. Generally you should use Clr which
210    points to the correct enabled/disabled class depending on the environment.
211    """
212
213    color_enabled = True
214
215    # Styles
216    RST = TerminalColor.RESET.value
217    BLD = TerminalColor.BOLD.value
218    UND = TerminalColor.UNDERLINE.value
219    INV = TerminalColor.INVERSE.value
220
221    # Normal foreground colors
222    BLK = TerminalColor.BLACK.value
223    RED = TerminalColor.RED.value
224    GRN = TerminalColor.GREEN.value
225    YLW = TerminalColor.YELLOW.value
226    BLU = TerminalColor.BLUE.value
227    MAG = TerminalColor.MAGENTA.value
228    CYN = TerminalColor.CYAN.value
229    WHT = TerminalColor.WHITE.value
230
231    # Normal background colors.
232    BBLK = TerminalColor.BG_BLACK.value
233    BRED = TerminalColor.BG_RED.value
234    BGRN = TerminalColor.BG_GREEN.value
235    BYLW = TerminalColor.BG_YELLOW.value
236    BBLU = TerminalColor.BG_BLUE.value
237    BMAG = TerminalColor.BG_MAGENTA.value
238    BCYN = TerminalColor.BG_CYAN.value
239    BWHT = TerminalColor.BG_WHITE.value
240
241    # Strong foreground colors
242    SBLK = TerminalColor.STRONG_BLACK.value
243    SRED = TerminalColor.STRONG_RED.value
244    SGRN = TerminalColor.STRONG_GREEN.value
245    SYLW = TerminalColor.STRONG_YELLOW.value
246    SBLU = TerminalColor.STRONG_BLUE.value
247    SMAG = TerminalColor.STRONG_MAGENTA.value
248    SCYN = TerminalColor.STRONG_CYAN.value
249    SWHT = TerminalColor.STRONG_WHITE.value
250
251    # Strong background colors.
252    SBBLK = TerminalColor.STRONG_BG_BLACK.value
253    SBRED = TerminalColor.STRONG_BG_RED.value
254    SBGRN = TerminalColor.STRONG_BG_GREEN.value
255    SBYLW = TerminalColor.STRONG_BG_YELLOW.value
256    SBBLU = TerminalColor.STRONG_BG_BLUE.value
257    SBMAG = TerminalColor.STRONG_BG_MAGENTA.value
258    SBCYN = TerminalColor.STRONG_BG_CYAN.value
259    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):
262class ClrNever(ClrBase):
263    """Convenience class for color terminal output.
264
265    This version has colors disabled. Generally you should use Clr which
266    points to the correct enabled/disabled class depending on the environment.
267    """
268
269    color_enabled = False
270
271    # Styles
272    RST = ''
273    BLD = ''
274    UND = ''
275    INV = ''
276
277    # Normal foreground colors
278    BLK = ''
279    RED = ''
280    GRN = ''
281    YLW = ''
282    BLU = ''
283    MAG = ''
284    CYN = ''
285    WHT = ''
286
287    # Normal background colors.
288    BBLK = ''
289    BRED = ''
290    BGRN = ''
291    BYLW = ''
292    BBLU = ''
293    BMAG = ''
294    BCYN = ''
295    BWHT = ''
296
297    # Strong foreground colors
298    SBLK = ''
299    SRED = ''
300    SGRN = ''
301    SYLW = ''
302    SBLU = ''
303    SMAG = ''
304    SCYN = ''
305    SWHT = ''
306
307    # Strong background colors.
308    SBBLK = ''
309    SBRED = ''
310    SBGRN = ''
311    SBYLW = ''
312    SBBLU = ''
313    SBMAG = ''
314    SBCYN = ''
315    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'>