-
-
Notifications
You must be signed in to change notification settings - Fork 70
Disable qtlog #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disable qtlog #58
Changes from all commits
46961ed
51c341f
d62c43e
7b70994
59f9396
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,8 @@ | |
import re | ||
|
||
from pytestqt.qt_compat import QtCore, QtTest, QApplication, QT_API, \ | ||
qInstallMsgHandler, QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg | ||
qInstallMsgHandler, qInstallMessageHandler, QtDebugMsg, QtWarningMsg, \ | ||
QtCriticalMsg, QtFatalMsg | ||
|
||
|
||
def _inject_qtest_methods(cls): | ||
|
@@ -631,30 +632,33 @@ def __init__(self, config): | |
self.config = config | ||
|
||
def pytest_runtest_setup(self, item): | ||
if item.get_marker('no_qt_log'): | ||
return | ||
m = item.get_marker('qt_log_ignore') | ||
if m: | ||
ignore_regexes = m.args | ||
else: | ||
ignore_regexes = self.config.getini('qt_log_ignore') | ||
item.qt_log_capture = _QtMessageCapture(ignore_regexes) | ||
previous_handler = qInstallMsgHandler(item.qt_log_capture._handle) | ||
item.qt_previous_handler = previous_handler | ||
item.qt_log_capture._start() | ||
|
||
@pytest.mark.hookwrapper | ||
def pytest_runtest_makereport(self, item, call): | ||
"""Add captured Qt messages to test item report if the call failed.""" | ||
|
||
outcome = yield | ||
report = outcome.result | ||
|
||
m = item.get_marker('qt_log_level_fail') | ||
if m: | ||
log_fail_level = m.args[0] | ||
else: | ||
log_fail_level = self.config.getini('qt_log_level_fail') | ||
assert log_fail_level in QtLoggingPlugin.LOG_FAIL_OPTIONS | ||
if not hasattr(item, 'qt_log_capture'): | ||
return | ||
|
||
if call.when == 'call': | ||
report = outcome.result | ||
|
||
m = item.get_marker('qt_log_level_fail') | ||
if m: | ||
log_fail_level = m.args[0] | ||
else: | ||
log_fail_level = self.config.getini('qt_log_level_fail') | ||
assert log_fail_level in QtLoggingPlugin.LOG_FAIL_OPTIONS | ||
|
||
# make test fail if any records were captured which match | ||
# log_fail_level | ||
|
@@ -682,15 +686,14 @@ def pytest_runtest_makereport(self, item, call): | |
long_repr.addsection('Captured Qt messages', | ||
'\n'.join(lines)) | ||
|
||
qInstallMsgHandler(item.qt_previous_handler) | ||
del item.qt_previous_handler | ||
item.qt_log_capture._stop() | ||
del item.qt_log_capture | ||
|
||
|
||
class _QtMessageCapture(object): | ||
""" | ||
Captures Qt messages when its `handle` method is installed using | ||
qInstallMsgHandler, and stores them into `messages` attribute. | ||
qInstallMsgHandler, and stores them into `records` attribute. | ||
|
||
:attr _records: list of Record instances. | ||
:attr _ignore_regexes: list of regexes (as strings) that define if a record | ||
|
@@ -700,13 +703,51 @@ class _QtMessageCapture(object): | |
def __init__(self, ignore_regexes): | ||
self._records = [] | ||
self._ignore_regexes = ignore_regexes or [] | ||
self._previous_handler = None | ||
|
||
def _start(self): | ||
""" | ||
Start receiving messages from Qt. | ||
""" | ||
if qInstallMsgHandler: | ||
previous_handler = qInstallMsgHandler(self._handle_no_context) | ||
else: | ||
assert qInstallMessageHandler | ||
previous_handler = qInstallMessageHandler(self._handle_with_context) | ||
self._previous_handler = previous_handler | ||
|
||
def _stop(self): | ||
""" | ||
Stop receiving messages from Qt, restoring the previously installed | ||
handler. | ||
""" | ||
if qInstallMsgHandler: | ||
qInstallMsgHandler(self._previous_handler) | ||
else: | ||
assert qInstallMessageHandler | ||
qInstallMessageHandler(self._previous_handler) | ||
|
||
@contextmanager | ||
def disabled(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps call this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm perhaps... I named it from "disabled within the context". Either way, I think it is too late to rename it now without breaking semantic versioning... 😶 |
||
""" | ||
Context manager that temporarily disables logging capture while | ||
inside it. | ||
""" | ||
self._stop() | ||
try: | ||
yield | ||
finally: | ||
self._start() | ||
|
||
_Context = namedtuple('_Context', 'file function line') | ||
|
||
def _handle(self, msg_type, message, context=None): | ||
def _append_new_record(self, msg_type, message, context): | ||
""" | ||
Method to be installed using qInstallMsgHandler, stores each message | ||
into the `messages` attribute. | ||
Creates a new Record instance and stores it. | ||
|
||
:param msg_type: Qt message typ | ||
:param message: message string, if bytes it will be converted to str. | ||
:param context: QMessageLogContext object or None | ||
""" | ||
def to_unicode(s): | ||
if isinstance(s, bytes): | ||
|
@@ -730,6 +771,20 @@ def to_unicode(s): | |
|
||
self._records.append(Record(msg_type, message, ignored, context)) | ||
|
||
def _handle_no_context(self, msg_type, message): | ||
""" | ||
Method to be installed using qInstallMsgHandler (Qt4), | ||
stores each message into the `_records` attribute. | ||
""" | ||
self._append_new_record(msg_type, message, context=None) | ||
|
||
def _handle_with_context(self, msg_type, context, message): | ||
""" | ||
Method to be installed using qInstallMessageHandler (Qt5), | ||
stores each message into the `_records` attribute. | ||
""" | ||
self._append_new_record(msg_type, message, context=context) | ||
|
||
@property | ||
def records(self): | ||
"""Access messages captured so far. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's useful... I checked the output in pytest-mccabe because that's what pytest-flakes did, and I wondered if I really should do things that way.