MCPcopy
hub / github.com/pytest-dev/pytest / catching_logs

Class catching_logs

src/_pytest/logging.py:339–385  ·  view source on GitHub ↗

Context manager that prepares the whole logging machinery properly.

Source from the content-addressed store, hash-verified

337
338# Not using @contextmanager for performance reasons.
339class catching_logs(Generic[_HandlerType]):
340 """Context manager that prepares the whole logging machinery properly."""
341
342 __slots__ = ("attached_loggers", "handler", "level", "orig_level")
343
344 def __init__(self, handler: _HandlerType, level: int | None = None) -> None:
345 self.handler = handler
346 self.level = level
347 self.attached_loggers: list[logging.Logger] = []
348
349 def __enter__(self) -> _HandlerType:
350 root_logger = logging.getLogger()
351 if self.level is not None:
352 self.handler.setLevel(self.level)
353 # Attach to root logger.
354 root_logger.addHandler(self.handler)
355 self.attached_loggers.append(root_logger)
356 # Attach to all non-propagating loggers (won't reach root).
357 # Note that will miss loggers that *become* non-propagating
358 # after the `__enter__`. Not worth the trouble for now.
359 for logger in root_logger.manager.loggerDict.values():
360 if (
361 isinstance(logger, logging.Logger)
362 and not logger.propagate
363 and logger is not root_logger
364 ):
365 logger.addHandler(self.handler)
366 self.attached_loggers.append(logger)
367 if self.level is not None:
368 # Non-propagating loggers still inherit the level (unless a logger
369 # explicitly set level), so only do this on the root logger.
370 self.orig_level = root_logger.level
371 root_logger.setLevel(min(self.orig_level, self.level))
372 return self.handler
373
374 def __exit__(
375 self,
376 exc_type: type[BaseException] | None,
377 exc_val: BaseException | None,
378 exc_tb: TracebackType | None,
379 ) -> None:
380 root_logger = logging.getLogger()
381 if self.level is not None:
382 root_logger.setLevel(self.orig_level)
383 for logger in self.attached_loggers:
384 logger.removeHandler(self.handler)
385 self.attached_loggers.clear()
386
387
388class LogCaptureHandler(logging_StreamHandler):

Callers 6

capturing_logsFunction · 0.90
pytest_sessionstartMethod · 0.85
pytest_collectionMethod · 0.85
pytest_runtestloopMethod · 0.85
_runtest_forMethod · 0.85
pytest_sessionfinishMethod · 0.85

Calls

no outgoing calls

Tested by 1

capturing_logsFunction · 0.72