@@ -338,6 +338,7 @@ def helper__build_test_id(item: pytest.Function) -> str:
338338
339339g_error_msg_count_key = pytest .StashKey [int ]()
340340g_warning_msg_count_key = pytest .StashKey [int ]()
341+ g_critical_msg_count_key = pytest .StashKey [int ]()
341342
342343# /////////////////////////////////////////////////////////////////////////////
343344
@@ -413,10 +414,17 @@ def helper__makereport__call(
413414assert type (outcome )== pluggy .Result # noqa: E721
414415
415416# --------
416- item_error_msg_count = item .stash .get (g_error_msg_count_key ,0 )
417- assert type (item_error_msg_count )== int # noqa: E721
418- assert item_error_msg_count >= 0
417+ item_error_msg_count1 = item .stash .get (g_error_msg_count_key ,0 )
418+ assert type (item_error_msg_count1 )== int # noqa: E721
419+ assert item_error_msg_count1 >= 0
419420
421+ item_error_msg_count2 = item .stash .get (g_critical_msg_count_key ,0 )
422+ assert type (item_error_msg_count2 )== int # noqa: E721
423+ assert item_error_msg_count2 >= 0
424+
425+ item_error_msg_count = item_error_msg_count1 + item_error_msg_count2
426+
427+ # --------
420428item_warning_msg_count = item .stash .get (g_warning_msg_count_key ,0 )
421429assert type (item_warning_msg_count )== int # noqa: E721
422430assert item_warning_msg_count >= 0
@@ -600,103 +608,87 @@ def pytest_runtest_makereport(item: pytest.Function, call: pytest.CallInfo):
600608# /////////////////////////////////////////////////////////////////////////////
601609
602610
603- class LogErrorWrapper2 :
611+ class LogWrapper2 :
604612_old_method :any
605- _counter :typing .Optional [int ]
613+ _err_counter :typing .Optional [int ]
614+ _warn_counter :typing .Optional [int ]
615+
616+ _critical_counter :typing .Optional [int ]
606617
607618# --------------------------------------------------------------------
608619def __init__ (self ):
609620self ._old_method = None
610- self ._counter = None
621+ self ._err_counter = None
622+ self ._warn_counter = None
623+
624+ self ._critical_counter = None
611625
612626# --------------------------------------------------------------------
613627def __enter__ (self ):
614628assert self ._old_method is None
615- assert self ._counter is None
616-
617- self ._old_method = logging .error
618- self ._counter = 0
619-
620- logging .error = self
621- return self
622-
623- # --------------------------------------------------------------------
624- def __exit__ (self ,exc_type ,exc_val ,exc_tb ):
625- assert self ._old_method is not None
626- assert self ._counter is not None
627-
628- assert logging .error is self
629-
630- logging .error = self ._old_method
631-
632- self ._old_method = None
633- self ._counter = None
634- return False
635-
636- # --------------------------------------------------------------------
637- def __call__ (self ,* args ,** kwargs ):
638- assert self ._old_method is not None
639- assert self ._counter is not None
640-
641- assert type (self ._counter )== int # noqa: E721
642- assert self ._counter >= 0
643-
644- r = self ._old_method (* args ,** kwargs )
645-
646- self ._counter += 1
647- assert self ._counter > 0
648-
649- return r
650-
651-
652- # /////////////////////////////////////////////////////////////////////////////
629+ assert self ._err_counter is None
630+ assert self ._warn_counter is None
653631
632+ assert self ._critical_counter is None
654633
655- class LogWarningWrapper2 :
656- _old_method :any
657- _counter :typing .Optional [int ]
634+ assert logging .root is not None
635+ assert isinstance (logging .root ,logging .RootLogger )
658636
659- # --------------------------------------------------------------------
660- def __init__ (self ):
661- self ._old_method = None
662- self ._counter = None
637+ self ._old_method = logging .root .handle
638+ self ._err_counter = 0
639+ self ._warn_counter = 0
663640
664- # --------------------------------------------------------------------
665- def __enter__ (self ):
666- assert self ._old_method is None
667- assert self ._counter is None
641+ self ._critical_counter = 0
668642
669- self ._old_method = logging .warning
670- self ._counter = 0
671-
672- logging .warning = self
643+ logging .root .handle = self
673644return self
674645
675646# --------------------------------------------------------------------
676647def __exit__ (self ,exc_type ,exc_val ,exc_tb ):
677648assert self ._old_method is not None
678- assert self ._counter is not None
649+ assert self ._err_counter is not None
650+ assert self ._warn_counter is not None
651+
652+ assert logging .root is not None
653+ assert isinstance (logging .root ,logging .RootLogger )
679654
680- assert logging .warning is self
655+ assert logging .root . handle is self
681656
682- logging .warning = self ._old_method
657+ logging .root . handle = self ._old_method
683658
684659self ._old_method = None
685- self ._counter = None
660+ self ._err_counter = None
661+ self ._warn_counter = None
662+ self ._critical_counter = None
686663return False
687664
688665# --------------------------------------------------------------------
689- def __call__ (self ,* args ,** kwargs ):
666+ def __call__ (self ,record :logging .LogRecord ):
667+ assert record is not None
668+ assert isinstance (record ,logging .LogRecord )
690669assert self ._old_method is not None
691- assert self ._counter is not None
692-
693- assert type (self ._counter )== int # noqa: E721
694- assert self ._counter >= 0
695-
696- r = self ._old_method (* args ,** kwargs )
697-
698- self ._counter += 1
699- assert self ._counter > 0
670+ assert self ._err_counter is not None
671+ assert self ._warn_counter is not None
672+ assert self ._critical_counter is not None
673+
674+ assert type (self ._err_counter )== int # noqa: E721
675+ assert self ._err_counter >= 0
676+ assert type (self ._warn_counter )== int # noqa: E721
677+ assert self ._warn_counter >= 0
678+ assert type (self ._critical_counter )== int # noqa: E721
679+ assert self ._critical_counter >= 0
680+
681+ r = self ._old_method (record )
682+
683+ if record .levelno == logging .ERROR :
684+ self ._err_counter += 1
685+ assert self ._err_counter > 0
686+ elif record .levelno == logging .WARNING :
687+ self ._warn_counter += 1
688+ assert self ._warn_counter > 0
689+ elif record .levelno == logging .CRITICAL :
690+ self ._critical_counter += 1
691+ assert self ._critical_counter > 0
700692
701693return r
702694
@@ -717,6 +709,13 @@ def pytest_pyfunc_call(pyfuncitem: pytest.Function):
717709assert pyfuncitem is not None
718710assert isinstance (pyfuncitem ,pytest .Function )
719711
712+ assert logging .root is not None
713+ assert isinstance (logging .root ,logging .RootLogger )
714+ assert logging .root .handle is not None
715+
716+ debug__log_handle_method = logging .root .handle
717+ assert debug__log_handle_method is not None
718+
720719debug__log_error_method = logging .error
721720assert debug__log_error_method is not None
722721
@@ -725,55 +724,56 @@ def pytest_pyfunc_call(pyfuncitem: pytest.Function):
725724
726725pyfuncitem .stash [g_error_msg_count_key ]= 0
727726pyfuncitem .stash [g_warning_msg_count_key ]= 0
727+ pyfuncitem .stash [g_critical_msg_count_key ]= 0
728728
729729try :
730- with LogErrorWrapper2 ()as logErrorWrapper ,LogWarningWrapper2 ()as logWarningWrapper :
731- assert type (logErrorWrapper )== LogErrorWrapper2 # noqa: E721
732- assert logErrorWrapper ._old_method is not None
733- assert type (logErrorWrapper ._counter )== int # noqa: E721
734- assert logErrorWrapper ._counter == 0
735- assert logging .error is logErrorWrapper
736-
737- assert type (logWarningWrapper )== LogWarningWrapper2 # noqa: E721
738- assert logWarningWrapper ._old_method is not None
739- assert type (logWarningWrapper ._counter )== int # noqa: E721
740- assert logWarningWrapper ._counter == 0
741- assert logging .warning is logWarningWrapper
730+ with LogWrapper2 ()as logWrapper :
731+ assert type (logWrapper )== LogWrapper2 # noqa: E721
732+ assert logWrapper ._old_method is not None
733+ assert type (logWrapper ._err_counter )== int # noqa: E721
734+ assert logWrapper ._err_counter == 0
735+ assert type (logWrapper ._warn_counter )== int # noqa: E721
736+ assert logWrapper ._warn_counter == 0
737+ assert type (logWrapper ._critical_counter )== int # noqa: E721
738+ assert logWrapper ._critical_counter == 0
739+ assert logging .root .handle is logWrapper
742740
743741r :pluggy .Result = yield
744742
745743assert r is not None
746744assert type (r )== pluggy .Result # noqa: E721
747745
748- assert logErrorWrapper ._old_method is not None
749- assert type (logErrorWrapper ._counter )== int # noqa: E721
750- assert logErrorWrapper ._counter >= 0
751- assert logging .error is logErrorWrapper
752-
753- assert logWarningWrapper ._old_method is not None
754- assert type (logWarningWrapper ._counter )== int # noqa: E721
755- assert logWarningWrapper ._counter >= 0
756- assert logging .warning is logWarningWrapper
746+ assert logWrapper ._old_method is not None
747+ assert type (logWrapper ._err_counter )== int # noqa: E721
748+ assert logWrapper ._err_counter >= 0
749+ assert type (logWrapper ._warn_counter )== int # noqa: E721
750+ assert logWrapper ._warn_counter >= 0
751+ assert type (logWrapper ._critical_counter )== int # noqa: E721
752+ assert logWrapper ._critical_counter >= 0
753+ assert logging .root .handle is logWrapper
757754
758755assert g_error_msg_count_key in pyfuncitem .stash
759756assert g_warning_msg_count_key in pyfuncitem .stash
757+ assert g_critical_msg_count_key in pyfuncitem .stash
760758
761759assert pyfuncitem .stash [g_error_msg_count_key ]== 0
762760assert pyfuncitem .stash [g_warning_msg_count_key ]== 0
761+ assert pyfuncitem .stash [g_critical_msg_count_key ]== 0
763762
764- pyfuncitem .stash [g_error_msg_count_key ]= logErrorWrapper ._counter
765- pyfuncitem .stash [g_warning_msg_count_key ]= logWarningWrapper ._counter
763+ pyfuncitem .stash [g_error_msg_count_key ]= logWrapper ._err_counter
764+ pyfuncitem .stash [g_warning_msg_count_key ]= logWrapper ._warn_counter
765+ pyfuncitem .stash [g_critical_msg_count_key ]= logWrapper ._critical_counter
766766
767767if r .exception is not None :
768768pass
769- elif logErrorWrapper ._counter == 0 :
770- pass
771- else :
772- assert logErrorWrapper ._counter > 0
769+ elif logWrapper ._err_counter > 0 :
770+ r .force_exception (SIGNAL_EXCEPTION ())
771+ elif logWrapper ._critical_counter > 0 :
773772r .force_exception (SIGNAL_EXCEPTION ())
774773finally :
775774assert logging .error is debug__log_error_method
776775assert logging .warning is debug__log_warning_method
776+ assert logging .root .handle == debug__log_handle_method
777777pass
778778
779779