1313import re
1414
1515from pytestqt .qt_compat import QtCore , QtTest , QApplication , QT_API , \
16- qInstallMsgHandler , QtDebugMsg , QtWarningMsg , QtCriticalMsg , QtFatalMsg
16+ qInstallMsgHandler , qInstallMessageHandler , QtDebugMsg , QtWarningMsg , \
17+ QtCriticalMsg , QtFatalMsg
1718
1819
1920def _inject_qtest_methods (cls ):
@@ -633,30 +634,33 @@ def __init__(self, config):
633634 self .config = config
634635
635636 def pytest_runtest_setup (self , item ):
637+ if item .get_marker ('no_qt_log' ):
638+ return
636639 m = item .get_marker ('qt_log_ignore' )
637640 if m :
638641 ignore_regexes = m .args
639642 else :
640643 ignore_regexes = self .config .getini ('qt_log_ignore' )
641644 item .qt_log_capture = _QtMessageCapture (ignore_regexes )
642- previous_handler = qInstallMsgHandler (item .qt_log_capture ._handle )
643- item .qt_previous_handler = previous_handler
645+ item .qt_log_capture ._start ()
644646
645647 @pytest .mark .hookwrapper
646648 def pytest_runtest_makereport (self , item , call ):
647649 """Add captured Qt messages to test item report if the call failed."""
648650
649651 outcome = yield
650- report = outcome .result
651-
652- m = item .get_marker ('qt_log_level_fail' )
653- if m :
654- log_fail_level = m .args [0 ]
655- else :
656- log_fail_level = self .config .getini ('qt_log_level_fail' )
657- assert log_fail_level in QtLoggingPlugin .LOG_FAIL_OPTIONS
652+ if not hasattr (item , 'qt_log_capture' ):
653+ return
658654
659655 if call .when == 'call' :
656+ report = outcome .result
657+
658+ m = item .get_marker ('qt_log_level_fail' )
659+ if m :
660+ log_fail_level = m .args [0 ]
661+ else :
662+ log_fail_level = self .config .getini ('qt_log_level_fail' )
663+ assert log_fail_level in QtLoggingPlugin .LOG_FAIL_OPTIONS
660664
661665 # make test fail if any records were captured which match
662666 # log_fail_level
@@ -684,15 +688,14 @@ def pytest_runtest_makereport(self, item, call):
684688 long_repr .addsection ('Captured Qt messages' ,
685689 '\n ' .join (lines ))
686690
687- qInstallMsgHandler (item .qt_previous_handler )
688- del item .qt_previous_handler
691+ item .qt_log_capture ._stop ()
689692 del item .qt_log_capture
690693
691694
692695class _QtMessageCapture (object ):
693696 """
694697 Captures Qt messages when its `handle` method is installed using
695- qInstallMsgHandler, and stores them into `messages ` attribute.
698+ qInstallMsgHandler, and stores them into `records ` attribute.
696699
697700 :attr _records: list of Record instances.
698701 :attr _ignore_regexes: list of regexes (as strings) that define if a record
@@ -702,13 +705,51 @@ class _QtMessageCapture(object):
702705 def __init__ (self , ignore_regexes ):
703706 self ._records = []
704707 self ._ignore_regexes = ignore_regexes or []
708+ self ._previous_handler = None
709+
710+ def _start (self ):
711+ """
712+ Start receiving messages from Qt.
713+ """
714+ if qInstallMsgHandler :
715+ previous_handler = qInstallMsgHandler (self ._handle_no_context )
716+ else :
717+ assert qInstallMessageHandler
718+ previous_handler = qInstallMessageHandler (self ._handle_with_context )
719+ self ._previous_handler = previous_handler
720+
721+ def _stop (self ):
722+ """
723+ Stop receiving messages from Qt, restoring the previously installed
724+ handler.
725+ """
726+ if qInstallMsgHandler :
727+ qInstallMsgHandler (self ._previous_handler )
728+ else :
729+ assert qInstallMessageHandler
730+ qInstallMessageHandler (self ._previous_handler )
731+
732+ @contextmanager
733+ def disabled (self ):
734+ """
735+ Context manager that temporarily disables logging capture while
736+ inside it.
737+ """
738+ self ._stop ()
739+ try :
740+ yield
741+ finally :
742+ self ._start ()
705743
706744 _Context = namedtuple ('_Context' , 'file function line' )
707745
708- def _handle (self , msg_type , message , context = None ):
746+ def _append_new_record (self , msg_type , message , context ):
709747 """
710- Method to be installed using qInstallMsgHandler, stores each message
711- into the `messages` attribute.
748+ Creates a new Record instance and stores it.
749+
750+ :param msg_type: Qt message typ
751+ :param message: message string, if bytes it will be converted to str.
752+ :param context: QMessageLogContext object or None
712753 """
713754 def to_unicode (s ):
714755 if isinstance (s , bytes ):
@@ -732,6 +773,20 @@ def to_unicode(s):
732773
733774 self ._records .append (Record (msg_type , message , ignored , context ))
734775
776+ def _handle_no_context (self , msg_type , message ):
777+ """
778+ Method to be installed using qInstallMsgHandler (Qt4),
779+ stores each message into the `_records` attribute.
780+ """
781+ self ._append_new_record (msg_type , message , context = None )
782+
783+ def _handle_with_context (self , msg_type , context , message ):
784+ """
785+ Method to be installed using qInstallMessageHandler (Qt5),
786+ stores each message into the `_records` attribute.
787+ """
788+ self ._append_new_record (msg_type , message , context = context )
789+
735790 @property
736791 def records (self ):
737792 """Access messages captured so far.
0 commit comments