@@ -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,54 @@ def __init__(self, config):
420
420
421
421
self .log_cli_handler = None
422
422
423
+ self ._setup_cli_logging ()
424
+
425
+ def _setup_cli_logging (self ):
426
+ terminal_reporter = self ._config .pluginmanager .get_plugin ("terminalreporter" )
427
+ # FIXME don't set verbosity level and derived attributes of
428
+ # terminalwriter directly
429
+ terminal_reporter .verbosity = self ._config .option .verbose
430
+ terminal_reporter .showheader = terminal_reporter .verbosity >= 0
431
+ terminal_reporter .showfspath = terminal_reporter .verbosity >= 0
432
+ terminal_reporter .showlongtestinfo = terminal_reporter .verbosity > 0
433
+
434
+ if self ._log_cli_enabled () and terminal_reporter is not None :
435
+ capture_manager = self ._config .pluginmanager .get_plugin ("capturemanager" )
436
+ log_cli_handler = _LiveLoggingStreamHandler (
437
+ terminal_reporter , capture_manager
438
+ )
439
+ log_cli_format = get_option_ini (
440
+ self ._config , "log_cli_format" , "log_format"
441
+ )
442
+ log_cli_date_format = get_option_ini (
443
+ self ._config , "log_cli_date_format" , "log_date_format"
444
+ )
445
+ if (
446
+ self ._config .option .color != "no"
447
+ and ColoredLevelFormatter .LEVELNAME_FMT_REGEX .search (log_cli_format )
448
+ ):
449
+ log_cli_formatter = ColoredLevelFormatter (
450
+ create_terminal_writer (self ._config ),
451
+ log_cli_format ,
452
+ datefmt = log_cli_date_format ,
453
+ )
454
+ else :
455
+ log_cli_formatter = logging .Formatter (
456
+ log_cli_format , datefmt = log_cli_date_format
457
+ )
458
+ log_cli_level = get_actual_log_level (
459
+ self ._config , "log_cli_level" , "log_level"
460
+ )
461
+ self .log_cli_handler = log_cli_handler
462
+ self .live_logs_context = lambda : catching_logs (
463
+ log_cli_handler , formatter = log_cli_formatter , level = log_cli_level
464
+ )
465
+ else :
466
+ self .live_logs_context = lambda : dummy_context_manager ()
467
+ # Note that the lambda for the live_logs_context is needed because
468
+ # live_logs_context can otherwise not be entered multiple times due
469
+ # to limitations of contextlib.contextmanager
470
+
423
471
def _log_cli_enabled (self ):
424
472
"""Return True if log_cli should be considered enabled, either explicitly
425
473
or because --log-cli-level was given in the command-line.
@@ -430,10 +478,6 @@ def _log_cli_enabled(self):
430
478
431
479
@pytest .hookimpl (hookwrapper = True , tryfirst = True )
432
480
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
481
with self .live_logs_context ():
438
482
if self .log_cli_handler :
439
483
self .log_cli_handler .set_when ("collection" )
@@ -513,7 +557,6 @@ def pytest_sessionfinish(self):
513
557
514
558
@pytest .hookimpl (hookwrapper = True , tryfirst = True )
515
559
def pytest_sessionstart (self ):
516
- self ._setup_cli_logging ()
517
560
with self .live_logs_context ():
518
561
if self .log_cli_handler :
519
562
self .log_cli_handler .set_when ("sessionstart" )
@@ -533,46 +576,6 @@ def pytest_runtestloop(self, session):
533
576
else :
534
577
yield # run all the tests
535
578
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
579
577
580
class _LiveLoggingStreamHandler (logging .StreamHandler ):
578
581
"""
0 commit comments