@@ -370,6 +370,8 @@ def get_actual_log_level(config, *setting_names):
370
370
)
371
371
372
372
373
+ # run after terminalreporter/capturemanager are configured
374
+ @pytest .hookimpl (trylast = True )
373
375
def pytest_configure (config ):
374
376
config .pluginmanager .register (LoggingPlugin (config ), "logging-plugin" )
375
377
@@ -388,8 +390,6 @@ def __init__(self, config):
388
390
389
391
# enable verbose output automatically if live logging is enabled
390
392
if self ._log_cli_enabled () and not config .getoption ("verbose" ):
391
- # sanity check: terminal reporter should not have been loaded at this point
392
- assert self ._config .pluginmanager .get_plugin ("terminalreporter" ) is None
393
393
config .option .verbose = 1
394
394
395
395
self .print_logs = get_option_ini (config , "log_print" )
@@ -420,6 +420,44 @@ def __init__(self, config):
420
420
421
421
self .log_cli_handler = None
422
422
423
+ terminal_reporter = self ._config .pluginmanager .get_plugin ("terminalreporter" )
424
+ if self ._log_cli_enabled () and terminal_reporter is not None :
425
+ capture_manager = self ._config .pluginmanager .get_plugin ("capturemanager" )
426
+ log_cli_handler = _LiveLoggingStreamHandler (
427
+ terminal_reporter , capture_manager
428
+ )
429
+ log_cli_format = get_option_ini (
430
+ self ._config , "log_cli_format" , "log_format"
431
+ )
432
+ log_cli_date_format = get_option_ini (
433
+ self ._config , "log_cli_date_format" , "log_date_format"
434
+ )
435
+ if (
436
+ self ._config .option .color != "no"
437
+ and ColoredLevelFormatter .LEVELNAME_FMT_REGEX .search (log_cli_format )
438
+ ):
439
+ log_cli_formatter = ColoredLevelFormatter (
440
+ create_terminal_writer (self ._config ),
441
+ log_cli_format ,
442
+ datefmt = log_cli_date_format ,
443
+ )
444
+ else :
445
+ log_cli_formatter = logging .Formatter (
446
+ log_cli_format , datefmt = log_cli_date_format
447
+ )
448
+ log_cli_level = get_actual_log_level (
449
+ self ._config , "log_cli_level" , "log_level"
450
+ )
451
+ self .log_cli_handler = log_cli_handler
452
+ self .live_logs_context = lambda : catching_logs (
453
+ log_cli_handler , formatter = log_cli_formatter , level = log_cli_level
454
+ )
455
+ else :
456
+ self .live_logs_context = lambda : dummy_context_manager ()
457
+ # Note that the lambda for the live_logs_context is needed because
458
+ # live_logs_context can otherwise not be entered multiple times due
459
+ # to limitations of contextlib.contextmanager
460
+
423
461
def _log_cli_enabled (self ):
424
462
"""Return True if log_cli should be considered enabled, either explicitly
425
463
or because --log-cli-level was given in the command-line.
@@ -430,10 +468,6 @@ def _log_cli_enabled(self):
430
468
431
469
@pytest .hookimpl (hookwrapper = True , tryfirst = True )
432
470
def pytest_collection (self ):
433
- # This has to be called before the first log message is logged,
434
- # so we can access the terminal reporter plugin.
435
- self ._setup_cli_logging ()
436
-
437
471
with self .live_logs_context ():
438
472
if self .log_cli_handler :
439
473
self .log_cli_handler .set_when ("collection" )
@@ -513,7 +547,6 @@ def pytest_sessionfinish(self):
513
547
514
548
@pytest .hookimpl (hookwrapper = True , tryfirst = True )
515
549
def pytest_sessionstart (self ):
516
- self ._setup_cli_logging ()
517
550
with self .live_logs_context ():
518
551
if self .log_cli_handler :
519
552
self .log_cli_handler .set_when ("sessionstart" )
@@ -533,46 +566,6 @@ def pytest_runtestloop(self, session):
533
566
else :
534
567
yield # run all the tests
535
568
536
- def _setup_cli_logging (self ):
537
- """Sets up the handler and logger for the Live Logs feature, if enabled."""
538
- terminal_reporter = self ._config .pluginmanager .get_plugin ("terminalreporter" )
539
- if self ._log_cli_enabled () and terminal_reporter is not None :
540
- capture_manager = self ._config .pluginmanager .get_plugin ("capturemanager" )
541
- log_cli_handler = _LiveLoggingStreamHandler (
542
- terminal_reporter , capture_manager
543
- )
544
- log_cli_format = get_option_ini (
545
- self ._config , "log_cli_format" , "log_format"
546
- )
547
- log_cli_date_format = get_option_ini (
548
- self ._config , "log_cli_date_format" , "log_date_format"
549
- )
550
- if (
551
- self ._config .option .color != "no"
552
- and ColoredLevelFormatter .LEVELNAME_FMT_REGEX .search (log_cli_format )
553
- ):
554
- log_cli_formatter = ColoredLevelFormatter (
555
- create_terminal_writer (self ._config ),
556
- log_cli_format ,
557
- datefmt = log_cli_date_format ,
558
- )
559
- else :
560
- log_cli_formatter = logging .Formatter (
561
- log_cli_format , datefmt = log_cli_date_format
562
- )
563
- log_cli_level = get_actual_log_level (
564
- self ._config , "log_cli_level" , "log_level"
565
- )
566
- self .log_cli_handler = log_cli_handler
567
- self .live_logs_context = lambda : catching_logs (
568
- log_cli_handler , formatter = log_cli_formatter , level = log_cli_level
569
- )
570
- else :
571
- self .live_logs_context = lambda : dummy_context_manager ()
572
- # Note that the lambda for the live_logs_context is needed because
573
- # live_logs_context can otherwise not be entered multiple times due
574
- # to limitations of contextlib.contextmanager
575
-
576
569
577
570
class _LiveLoggingStreamHandler (logging .StreamHandler ):
578
571
"""
0 commit comments