Files

83 lines
3.3 KiB
Python

"""
Debug utilities for COCO Tools with simple/verbose logging control.
"""
import logging
from typing import List, Dict, Any, Optional
# Global debug mode control - default to simple
DEBUG_MODE = "simple" # "simple" or "verbose"
# Flag to prevent multiple logging configurations
_LOGGING_CONFIGURED = False
def setup_logging(level: int = logging.INFO):
"""
Centralized logging configuration for all COCO Tools modules.
Should be called once at module level to avoid conflicts.
"""
global _LOGGING_CONFIGURED
if not _LOGGING_CONFIGURED:
# Check if root logger already has handlers to prevent duplicate setup
if not logging.getLogger().handlers:
logging.basicConfig(level=level)
_LOGGING_CONFIGURED = True
def set_debug_mode(mode: str):
"""Set global debug mode"""
global DEBUG_MODE
DEBUG_MODE = mode.lower() if mode.lower() in ["simple", "verbose"] else "simple"
def get_debug_mode() -> str:
"""Get current debug mode"""
return DEBUG_MODE
def debug_log(logger: logging.Logger, level: str, simple_msg: str, verbose_msg: Optional[str] = None, **kwargs):
"""
Log with debug verbosity control.
Args:
logger: Logger instance
level: Log level ("info", "warning", "error", "debug")
simple_msg: Short message for simple mode
verbose_msg: Detailed message for verbose mode (if None, uses simple_msg)
**kwargs: Additional context for verbose mode
"""
message = simple_msg if DEBUG_MODE == "simple" else (verbose_msg or simple_msg)
# Add context info in verbose mode
if DEBUG_MODE == "verbose" and kwargs:
context_parts = [f"{k}={v}" for k, v in kwargs.items()]
message += f" [{', '.join(context_parts)}]"
# Log based on level
if level.lower() == "info":
logger.info(message)
elif level.lower() == "warning":
logger.warning(message)
elif level.lower() == "error":
logger.error(message)
elif level.lower() == "debug":
logger.debug(message)
def format_layer_names(layer_names: List[str], max_simple: int = None) -> str:
"""Format layer names for logging - show all layer names as they're important for users"""
# Always show all layer names as users need to know what's available
return ', '.join(layer_names)
def format_tensor_info(tensor_shape: tuple, tensor_dtype: Any, name: str = "") -> str:
"""Format tensor information for logging"""
if DEBUG_MODE == "simple":
return f"{name} shape={tensor_shape}" if name else f"shape={tensor_shape}"
return f"{name} shape={tensor_shape}, dtype={tensor_dtype}" if name else f"shape={tensor_shape}, dtype={tensor_dtype}"
def create_fallback_functions():
"""
Create fallback functions for cases where debug_utils import fails.
Returns a dictionary of fallback functions following single responsibility principle.
"""
return {
'debug_log': lambda logger, level, simple_msg, verbose_msg=None, **kwargs: getattr(logger, level.lower())(simple_msg),
'format_layer_names': lambda layer_names, max_simple=None: ', '.join(layer_names),
'format_tensor_info': lambda tensor_shape, tensor_dtype, name="": f"{name} shape={tensor_shape}" if name else f"shape={tensor_shape}",
'generate_preview_for_comfyui': lambda image_tensor, source_path="", is_sequence=False, frame_index=0: None
}