Source code for gyoza.logging.logger

"""Logger singleton for gyoza operations."""

import logging
from typing import Final


[docs] class GyozaLogger: """ Singleton logger for gyoza operations. Provides specialized logging methods for gyoza operations with custom formatting. """ _instance: "GyozaLogger | None" = None _initialized: bool = False def __new__(cls) -> "GyozaLogger": """Create or return the singleton instance.""" if cls._instance is None: cls._instance = super().__new__(cls) cls._instance._initialized = False return cls._instance def __init__(self) -> None: """Initialize the logger if not already initialized.""" if hasattr(self, "_initialized") and self._initialized: return self._logger = logging.getLogger("gyoza") self._logger.setLevel(logging.INFO) # Only add handler if one doesn't exist if not self._logger.handlers: handler = logging.StreamHandler() handler.setLevel(logging.INFO) # Custom formatter for gyoza logs formatter = logging.Formatter( fmt="[GYOZA] %(message)s", ) handler.setFormatter(formatter) self._logger.addHandler(handler) # Track current progress for relative increments self._current_progress: float = 0.0 self._initialized = True
[docs] def info(self, message: str) -> None: """ Log an info message. Parameters ---------- message : str The message to log Examples -------- >>> from gyoza import logger >>> logger.info("Processing started") """ formatted_message = f"[INFO] {message}" self._logger.info(formatted_message)
[docs] def reset(self) -> None: """ Reset the progress counter to 0. Useful for starting a new operation or resetting progress tracking. Examples -------- >>> from gyoza import logger >>> logger.progress(50.0) >>> logger.reset() # Reset to 0% >>> logger.progress(25.0, relative=True) # Now at 25% """ self._current_progress = 0.0
[docs] def progress(self, value: float, relative: bool = False) -> None: """ Log a progress value. Parameters ---------- value : float Progress value between 0 and 100, or increment if relative=True relative : bool, default=False If True, adds value to current progress instead of setting absolute value Raises ------ ValueError If value is not between 0 and 100 (when relative=False), if value is negative (when relative=True), or if absolute value would decrease progress. """ if relative: # For relative increments, value must be positive if value < 0: error_msg = ( f"Relative progress increment must be non-negative, got {value}" ) raise ValueError(error_msg) # Add to current progress and cap at 100% self._current_progress = min(100.0, self._current_progress + value) final_value = self._current_progress else: # For absolute values, validate range if not 0 <= value <= 100: error_msg = f"Progress value must be between 0 and 100, got {value}" raise ValueError(error_msg) if value < self._current_progress: error_msg = ( f"Progress cannot decrease from " f"{self._current_progress:.2f}% to {value:.2f}%" ) raise ValueError(error_msg) self._current_progress = value final_value = value formatted_message = f"[PROGRESS] {final_value:.2f}%" self._logger.info(formatted_message)
# Create singleton instance logger: Final[GyozaLogger] = GyozaLogger()