Even though I don't like C's do everything yourself, I love to reinvent the wheel for minor things.

This snippet I put here for myself, but you're encouraged to use it.

The loop below the class is to make Colors's be at the same time non-instantiated and have all the colors dynamically assigned from the dictionary.

Colors.color-lowercase are methods for wrapping a string as color + string + reset, and Colors.color-uppercase are corresponding color codes as strings.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Colors:
    colors: dict[str, str] =  {
        "black": "\033[30m",
        "grey": "\033[90m",
        "white": "\033[37m",
        
        "red": "\033[91m",
        "green": "\033[92m",
        "yellow": "\033[93m",

        "blue": "\033[34m",
        "magenta": "\033[35m",
        "cyan": "\033[36m",

        "bold": "\033[1m",
        "italic": "\033[3m",
        "underline": "\033[4m",

        "reset": "\033[0m"
    }

for name in Colors.colors:
    setattr(Colors, name.upper(), Colors.colors[name])

    if name != "reset":
        def color(cls, arg, name = name):
            return Colors.colors[name] + arg + Colors.colors["reset"]

        setattr(Colors, name.lower(), classmethod(color))