3RNN/Lib/site-packages/termcolor/termcolor.py
2024-05-26 19:49:15 +02:00

213 lines
5.8 KiB
Python

# Copyright (c) 2008-2011 Volvox Development Team
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Author: Konstantin Lepa <konstantin.lepa@gmail.com>
"""ANSI color formatting for output in terminal."""
from __future__ import annotations
import io
import os
import sys
import warnings
from typing import Any, Iterable
from ._types import Attribute, Color, Highlight
def __getattr__(name: str) -> list[str]:
if name == "__ALL__":
warnings.warn(
"__ALL__ is deprecated and will be removed in termcolor 3. "
"Use __all__ instead.",
DeprecationWarning,
stacklevel=2,
)
return ["colored", "cprint"]
msg = f"module '{__name__}' has no attribute '{name}'"
raise AttributeError(msg)
ATTRIBUTES: dict[Attribute, int] = {
"bold": 1,
"dark": 2,
"underline": 4,
"blink": 5,
"reverse": 7,
"concealed": 8,
}
HIGHLIGHTS: dict[Highlight, int] = {
"on_black": 40,
"on_grey": 40, # Actually black but kept for backwards compatibility
"on_red": 41,
"on_green": 42,
"on_yellow": 43,
"on_blue": 44,
"on_magenta": 45,
"on_cyan": 46,
"on_light_grey": 47,
"on_dark_grey": 100,
"on_light_red": 101,
"on_light_green": 102,
"on_light_yellow": 103,
"on_light_blue": 104,
"on_light_magenta": 105,
"on_light_cyan": 106,
"on_white": 107,
}
COLORS: dict[Color, int] = {
"black": 30,
"grey": 30, # Actually black but kept for backwards compatibility
"red": 31,
"green": 32,
"yellow": 33,
"blue": 34,
"magenta": 35,
"cyan": 36,
"light_grey": 37,
"dark_grey": 90,
"light_red": 91,
"light_green": 92,
"light_yellow": 93,
"light_blue": 94,
"light_magenta": 95,
"light_cyan": 96,
"white": 97,
}
RESET = "\033[0m"
def _can_do_colour(
*, no_color: bool | None = None, force_color: bool | None = None
) -> bool:
"""Check env vars and for tty/dumb terminal"""
# First check overrides:
# "User-level configuration files and per-instance command-line arguments should
# override $NO_COLOR. A user should be able to export $NO_COLOR in their shell
# configuration file as a default, but configure a specific program in its
# configuration file to specifically enable color."
# https://no-color.org
if no_color is not None and no_color:
return False
if force_color is not None and force_color:
return True
# Then check env vars:
if "ANSI_COLORS_DISABLED" in os.environ:
return False
if "NO_COLOR" in os.environ:
return False
if "FORCE_COLOR" in os.environ:
return True
# Then check system:
if os.environ.get("TERM") == "dumb":
return False
if not hasattr(sys.stdout, "fileno"):
return False
try:
return os.isatty(sys.stdout.fileno())
except io.UnsupportedOperation:
return sys.stdout.isatty()
def colored(
text: object,
color: Color | None = None,
on_color: Highlight | None = None,
attrs: Iterable[Attribute] | None = None,
*,
no_color: bool | None = None,
force_color: bool | None = None,
) -> str:
"""Colorize text.
Available text colors:
black, red, green, yellow, blue, magenta, cyan, white,
light_grey, dark_grey, light_red, light_green, light_yellow, light_blue,
light_magenta, light_cyan.
Available text highlights:
on_black, on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white,
on_light_grey, on_dark_grey, on_light_red, on_light_green, on_light_yellow,
on_light_blue, on_light_magenta, on_light_cyan.
Available attributes:
bold, dark, underline, blink, reverse, concealed.
Example:
colored('Hello, World!', 'red', 'on_black', ['bold', 'blink'])
colored('Hello, World!', 'green')
"""
result = str(text)
if not _can_do_colour(no_color=no_color, force_color=force_color):
return result
fmt_str = "\033[%dm%s"
if color is not None:
result = fmt_str % (COLORS[color], result)
if on_color is not None:
result = fmt_str % (HIGHLIGHTS[on_color], result)
if attrs is not None:
for attr in attrs:
result = fmt_str % (ATTRIBUTES[attr], result)
result += RESET
return result
def cprint(
text: object,
color: Color | None = None,
on_color: Highlight | None = None,
attrs: Iterable[Attribute] | None = None,
*,
no_color: bool | None = None,
force_color: bool | None = None,
**kwargs: Any,
) -> None:
"""Print colorized text.
It accepts arguments of print function.
"""
print(
(
colored(
text,
color,
on_color,
attrs,
no_color=no_color,
force_color=force_color,
)
),
**kwargs,
)