diff --git a/base.py b/base.py new file mode 100644 index 0000000000000000000000000000000000000000..bc3c578edfd99c701a66f915053b91489ddd7651 --- /dev/null +++ b/base.py @@ -0,0 +1,73 @@ +""" +Simple base operations, in particular colored message output. +""" +import logging +import typing as tg + +import rich + + +num_errors = 0 +msgs_seen = set() +loglevel = logging.INFO +loglevels = dict(DEBUG=logging.DEBUG, INFO=logging.INFO, WARNING=logging.WARNING, + ERROR=logging.ERROR, CRITICAL=logging.CRITICAL) + + +class CritialError(Exception): + pass + + +def set_loglevel(level: str): + global loglevels, loglevel + if level in loglevels: + global loglevel + loglevel = loglevels[level] + else: + pass # simply ignore nonexisting loglevels + + +def debug(msg: str): + if loglevel <= logging.DEBUG: + rich_print(msg) + + +def info(msg: str): + if loglevel <= logging.INFO: + rich_print(msg, "green") + + +def warning(msg: str, file: str = None, file2: str = None): + if loglevel <= logging.WARNING: + msg = _process_params(msg, file, file2) + rich_print(msg, "yellow") + + +def error(msg: str, file: str = None, file2: str = None): + if loglevel <= logging.ERROR: + msg = _process_params(msg, file, file2) + rich_print(msg, "red", count=1) + + +def critical(msg: str): + rich_print(msg, "red", count=1) + raise CritialError(msg) + + +def rich_print(msg: str, enclose_in_tag: tg.Optional[str] = None, count=0): + """Print any message, but each one only once.""" + global num_errors, msgs_seen + if msg not in msgs_seen: + msgs_seen.add(msg) + num_errors += count + if enclose_in_tag: + msg = f"[{enclose_in_tag}]{msg}[/{enclose_in_tag}]" + rich.print(msg) + + +def _process_params(msg: str, file: tg.Optional[str], file2: tg.Optional[str]): + if file and file2: + msg = f"Files '{file}' and '{file2}':\n {msg}" + elif file: + msg = f"File '{file}':\n {msg}" + return msg