"""Compatibility shim providing keyword-argument logging API on top of stdlib logging. This module lets the rest of the codebase keep the keyword-argument logging style (``log.info("event", key=value)``) while using only the Python standard library ``logging`` module underneath. """ from __future__ import annotations import logging from typing import Any class _CompatLogger: """Wraps a stdlib :class:`logging.Logger` to accept keyword arguments.""" def __init__(self, logger: logging.Logger) -> None: self._logger = logger _STDLIB_LOG_KWARGS = frozenset(("exc_info", "extra", "stack_info", "stacklevel")) def _log(self, level: int, event: str, **kwargs: Any) -> None: stdlib_kwargs: dict[str, Any] = {} for k in self._STDLIB_LOG_KWARGS: v = kwargs.pop(k, None) if v is not None: stdlib_kwargs[k] = v if kwargs: stdlib_kwargs["extra"] = kwargs self._logger.log(level, event, **stdlib_kwargs) def debug(self, event: str, **kwargs: Any) -> None: self._log(logging.DEBUG, event, **kwargs) def info(self, event: str, **kwargs: Any) -> None: self._log(logging.INFO, event, **kwargs) def warning(self, event: str, **kwargs: Any) -> None: self._log(logging.WARNING, event, **kwargs) def warn(self, event: str, **kwargs: Any) -> None: self._log(logging.WARNING, event, **kwargs) def error(self, event: str, **kwargs: Any) -> None: self._log(logging.ERROR, event, **kwargs) def critical(self, event: str, **kwargs: Any) -> None: self._log(logging.CRITICAL, event, **kwargs) def exception(self, event: str, **kwargs: Any) -> None: self._log(logging.ERROR, event, exc_info=True, **kwargs) def bind(self, **kwargs: Any) -> "_CompatLogger": """Return a new logger with bound context (no-op for stdlib).""" return self def get_logger(name: str | None = None) -> _CompatLogger: """Get a compatibility logger wrapping the stdlib logger for *name*. If *name* is ``None`` the caller's module name is used. """ if name is None: import sys # Walk up the stack to find the caller's module. frame = sys._getframe(1) module = frame.f_globals.get("__name__", "__main__") name = module return _CompatLogger(logging.getLogger(name))