Skip to content

Commit aaada5b

Browse files
committed
Qt API lazy load in qt_compat and qt_api config option
Fix #129
1 parent cef8b39 commit aaada5b

16 files changed

+607
-563
lines changed

CHANGELOG.rst

+11
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,19 @@ New Features
3737
is met or a timeout is reached. Useful for testing some features in X window environments
3838
due to its asynchronous nature.
3939

40+
* Now which Qt binding ``pytest-qt`` should use can be configured by the ``qt_api`` config option.
41+
Thanks `@The-Compiler`_ for the request (`#129`_).
42+
43+
- ``PYTEST_QT_FORCE_PYQT`` environment variable is no longer supported.
44+
45+
- While ``pytestqt.qt_compat`` is an internal module and shouldn't be imported directly,
46+
it is known that some test suites did import it. This module now uses a lazy-load mechanism
47+
to load Qt classes and objects, so the old symbols (``QtCore``, ``QApplication``, etc.) are
48+
no longer available from it.
49+
4050
.. _#134: https://github.com/pytest-dev/pytest-qt/issues/134
4151
.. _#63: https://github.com/pytest-dev/pytest-qt/pull/63
52+
.. _#129: https://github.com/pytest-dev/pytest-qt/issues/129
4253

4354

4455
Other Changes

README.rst

+14-3
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,20 @@ this order:
8080
- ``PySide``
8181
- ``PyQt4``
8282

83-
To force a particular API, set the environment variable ``PYTEST_QT_API`` to
84-
``pyqt5``, ``pyside``, ``pyqt4``, or ``pyqt4v2``. ``pyqt4v2`` sets the ``PyQt4``
85-
API to `version 2 <http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html>`_.
83+
To force a particular API, set the configuration variable ``qt_api`` in your ``pytest.ini`` file to
84+
``pyqt5``, ``pyside``, ``pyqt4`` or ``pyqt4v2``. ``pyqt4v2`` sets the ``PyQt4``
85+
API to `version 2 <version2>`_.
86+
87+
.. code-block:: ini
88+
[pytest]
89+
qt_api=pyqt5
90+
91+
92+
Alternatively, you can set the ``PYTEST_QT_API`` environment
93+
variable to the same values described above (the environment variable wins over the configuration
94+
if both are set).
95+
96+
.. _version2: http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html
8697

8798

8899
Documentation

docs/intro.rst

+12-2
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,19 @@ this order:
3838
- ``PySide``
3939
- ``PyQt4``
4040

41-
To force a particular API, set the environment variable ``PYTEST_QT_API`` to
41+
To force a particular API, set the configuration variable ``qt_api`` in your ``pytest.ini`` file to
4242
``pyqt5``, ``pyside``, ``pyqt4`` or ``pyqt4v2``. ``pyqt4v2`` sets the ``PyQt4``
43-
API to `version 2 <version2>`_
43+
API to `version 2 <version2>`_.
44+
45+
.. code-block:: ini
46+
47+
[pytest]
48+
qt_api=pyqt5
49+
50+
51+
Alternatively, you can set the ``PYTEST_QT_API`` environment
52+
variable to the same values described above (the environment variable wins over the configuration
53+
if both are set).
4454

4555
.. _version2: http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html
4656

pytestqt/logging.py

+23-18
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
import re
55
from py._code.code import TerminalRepr, ReprFileLocation
66
import pytest
7-
from pytestqt.qt_compat import qInstallMsgHandler, qInstallMessageHandler, \
8-
QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg
7+
from pytestqt.qt_compat import qt_api
98

109

1110
class QtLoggingPlugin(object):
@@ -71,6 +70,12 @@ def pytest_runtest_makereport(self, item, call):
7170
long_repr = getattr(report, 'longrepr', None)
7271
if hasattr(long_repr, 'addsection'): # pragma: no cover
7372
log_format = self.config.getoption('qt_log_format')
73+
if log_format is None:
74+
if qt_api.pytest_qt_api == 'pyqt5':
75+
log_format = '{rec.context.file}:{rec.context.function}:' \
76+
'{rec.context.line}:\n {rec.type_name}: {rec.message}'
77+
else:
78+
log_format = '{rec.type_name}: {rec.message}'
7479
lines = []
7580
for rec in item.qt_log_capture.records:
7681
suffix = ' (IGNORED)' if rec.ignored else ''
@@ -103,23 +108,23 @@ def _start(self):
103108
"""
104109
Start receiving messages from Qt.
105110
"""
106-
if qInstallMsgHandler:
107-
previous_handler = qInstallMsgHandler(self._handle_no_context)
111+
if qt_api.qInstallMsgHandler:
112+
previous_handler = qt_api.qInstallMsgHandler(self._handle_no_context)
108113
else:
109-
assert qInstallMessageHandler
110-
previous_handler = qInstallMessageHandler(self._handle_with_context)
114+
assert qt_api.qInstallMessageHandler
115+
previous_handler = qt_api.qInstallMessageHandler(self._handle_with_context)
111116
self._previous_handler = previous_handler
112117

113118
def _stop(self):
114119
"""
115120
Stop receiving messages from Qt, restoring the previously installed
116121
handler.
117122
"""
118-
if qInstallMsgHandler:
119-
qInstallMsgHandler(self._previous_handler)
123+
if qt_api.qInstallMsgHandler:
124+
qt_api.qInstallMsgHandler(self._previous_handler)
120125
else:
121-
assert qInstallMessageHandler
122-
qInstallMessageHandler(self._previous_handler)
126+
assert qt_api.qInstallMessageHandler
127+
qt_api.qInstallMessageHandler(self._previous_handler)
123128

124129
@contextmanager
125130
def disabled(self):
@@ -230,10 +235,10 @@ def _get_msg_type_name(cls, msg_type):
230235
"""
231236
if not getattr(cls, '_type_name_map', None):
232237
cls._type_name_map = {
233-
QtDebugMsg: 'QtDebugMsg',
234-
QtWarningMsg: 'QtWarningMsg',
235-
QtCriticalMsg: 'QtCriticalMsg',
236-
QtFatalMsg: 'QtFatalMsg',
238+
qt_api.QtDebugMsg: 'QtDebugMsg',
239+
qt_api.QtWarningMsg: 'QtWarningMsg',
240+
qt_api.QtCriticalMsg: 'QtCriticalMsg',
241+
qt_api.QtFatalMsg: 'QtFatalMsg',
237242
}
238243
return cls._type_name_map[msg_type]
239244

@@ -245,10 +250,10 @@ def _get_log_type_name(cls, msg_type):
245250
"""
246251
if not getattr(cls, '_log_type_name_map', None):
247252
cls._log_type_name_map = {
248-
QtDebugMsg: 'DEBUG',
249-
QtWarningMsg: 'WARNING',
250-
QtCriticalMsg: 'CRITICAL',
251-
QtFatalMsg: 'FATAL',
253+
qt_api.QtDebugMsg: 'DEBUG',
254+
qt_api.QtWarningMsg: 'WARNING',
255+
qt_api.QtCriticalMsg: 'CRITICAL',
256+
qt_api.QtFatalMsg: 'FATAL',
252257
}
253258
return cls._log_type_name_map[msg_type]
254259

0 commit comments

Comments
 (0)