Source code for pyphi.log

# log.py
"""Utilities for logging and progress bars."""

from __future__ import annotations

import logging
from pathlib import Path

from tqdm import tqdm

_LOG_FORMAT = "%(asctime)s [%(name)s] %(levelname)s %(processName)s: %(message)s"


[docs] class TqdmHandler(logging.StreamHandler): """Logging handler that writes through ``tqdm`` in order to not break progress bars. """
[docs] def emit(self, record): try: msg = self.format(record) tqdm.write(msg, file=self.stream, end=self.terminator) self.flush() except Exception: # pylint: disable=broad-except self.handleError(record)
[docs] def enable_logging(level: str = "INFO", file: str | Path | None = None) -> None: """Route PyPhi's logs to the console or a file. With no arguments, ``INFO``-and-above messages from the ``pyphi`` logger are written to stderr through a progress-bar-safe handler. Pass ``file`` to write to that path instead. Calling this again replaces the handler a previous call installed (handlers do not stack). Parameters ---------- level A standard level name (``"DEBUG"``, ``"INFO"``, ``"WARNING"``, ``"ERROR"``, ``"CRITICAL"``). An unknown name raises ``ValueError``. file A path to log to. If ``None``, logs go to stderr. """ logger = logging.getLogger("pyphi") for installed in list(logger.handlers): if not isinstance(installed, logging.NullHandler): logger.removeHandler(installed) installed.close() handler: logging.Handler = ( TqdmHandler() if file is None else logging.FileHandler(str(file)) ) handler.setFormatter(logging.Formatter(_LOG_FORMAT)) handler.setLevel(level) logger.addHandler(handler) logger.setLevel(level) logger.propagate = False