Skip to content
12 changes: 12 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ However, this required some backwards-incompatible changes:
on timeouts. You can set ``qt_wait_signal_raising = false`` in your config to
get back the old behaviour.

- ``PYTEST_QT_FORCE_PYQT`` environment variable is no longer supported. Set ``PYTEST_QT_API``
to the appropriate value instead.


New Features
~~~~~~~~~~~~
Expand All @@ -41,9 +44,18 @@ New Features
evaluate if the arguments of emitted signals should resume execution or not.
Thanks `@MShekow`_ for the PR (`#141`_).

* Now which Qt binding ``pytest-qt`` will use can be configured by the ``qt_api`` config option.
Thanks `@The-Compiler`_ for the request (`#129`_).

* While ``pytestqt.qt_compat`` is an internal module and shouldn't be imported directly,
it is known that some test suites did import it. This module now uses a lazy-load mechanism
to load Qt classes and objects, so the old symbols (``QtCore``, ``QApplication``, etc.) are
no longer available from it.

.. _#134: https://github.com/pytest-dev/pytest-qt/issues/134
.. _#141: https://github.com/pytest-dev/pytest-qt/pull/141
.. _#63: https://github.com/pytest-dev/pytest-qt/pull/63
.. _#129: https://github.com/pytest-dev/pytest-qt/issues/129


Other Changes
Expand Down
17 changes: 14 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,20 @@ this order:
- ``PySide``
- ``PyQt4``

To force a particular API, set the environment variable ``PYTEST_QT_API`` to
``pyqt5``, ``pyside``, ``pyqt4``, or ``pyqt4v2``. ``pyqt4v2`` sets the ``PyQt4``
API to `version 2 <http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html>`_.
To force a particular API, set the configuration variable ``qt_api`` in your ``pytest.ini`` file to
``pyqt5``, ``pyside``, ``pyqt4`` or ``pyqt4v2``. ``pyqt4v2`` sets the ``PyQt4``
API to `version 2 <version2>`_.

.. code-block:: ini
[pytest]
qt_api=pyqt5


Alternatively, you can set the ``PYTEST_QT_API`` environment
variable to the same values described above (the environment variable wins over the configuration
if both are set).

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


Documentation
Expand Down
14 changes: 12 additions & 2 deletions docs/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,19 @@ this order:
- ``PySide``
- ``PyQt4``

To force a particular API, set the environment variable ``PYTEST_QT_API`` to
To force a particular API, set the configuration variable ``qt_api`` in your ``pytest.ini`` file to
``pyqt5``, ``pyside``, ``pyqt4`` or ``pyqt4v2``. ``pyqt4v2`` sets the ``PyQt4``
API to `version 2 <version2>`_
API to `version 2 <version2>`_.

.. code-block:: ini

[pytest]
qt_api=pyqt5


Alternatively, you can set the ``PYTEST_QT_API`` environment
variable to the same values described above (the environment variable wins over the configuration
if both are set).

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

Expand Down
41 changes: 23 additions & 18 deletions pytestqt/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
import re
from py._code.code import TerminalRepr, ReprFileLocation
import pytest
from pytestqt.qt_compat import qInstallMsgHandler, qInstallMessageHandler, \
QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg
from pytestqt.qt_compat import qt_api


class QtLoggingPlugin(object):
Expand Down Expand Up @@ -71,6 +70,12 @@ def pytest_runtest_makereport(self, item, call):
long_repr = getattr(report, 'longrepr', None)
if hasattr(long_repr, 'addsection'): # pragma: no cover
log_format = self.config.getoption('qt_log_format')
if log_format is None:
if qt_api.pytest_qt_api == 'pyqt5':
log_format = '{rec.context.file}:{rec.context.function}:' \
'{rec.context.line}:\n {rec.type_name}: {rec.message}'
else:
log_format = '{rec.type_name}: {rec.message}'
lines = []
for rec in item.qt_log_capture.records:
suffix = ' (IGNORED)' if rec.ignored else ''
Expand Down Expand Up @@ -103,23 +108,23 @@ def _start(self):
"""
Start receiving messages from Qt.
"""
if qInstallMsgHandler:
previous_handler = qInstallMsgHandler(self._handle_no_context)
if qt_api.qInstallMsgHandler:
previous_handler = qt_api.qInstallMsgHandler(self._handle_no_context)
else:
assert qInstallMessageHandler
previous_handler = qInstallMessageHandler(self._handle_with_context)
assert qt_api.qInstallMessageHandler
previous_handler = qt_api.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)
if qt_api.qInstallMsgHandler:
qt_api.qInstallMsgHandler(self._previous_handler)
else:
assert qInstallMessageHandler
qInstallMessageHandler(self._previous_handler)
assert qt_api.qInstallMessageHandler
qt_api.qInstallMessageHandler(self._previous_handler)

@contextmanager
def disabled(self):
Expand Down Expand Up @@ -230,10 +235,10 @@ def _get_msg_type_name(cls, msg_type):
"""
if not getattr(cls, '_type_name_map', None):
cls._type_name_map = {
QtDebugMsg: 'QtDebugMsg',
QtWarningMsg: 'QtWarningMsg',
QtCriticalMsg: 'QtCriticalMsg',
QtFatalMsg: 'QtFatalMsg',
qt_api.QtDebugMsg: 'QtDebugMsg',
qt_api.QtWarningMsg: 'QtWarningMsg',
qt_api.QtCriticalMsg: 'QtCriticalMsg',
qt_api.QtFatalMsg: 'QtFatalMsg',
}
return cls._type_name_map[msg_type]

Expand All @@ -245,10 +250,10 @@ def _get_log_type_name(cls, msg_type):
"""
if not getattr(cls, '_log_type_name_map', None):
cls._log_type_name_map = {
QtDebugMsg: 'DEBUG',
QtWarningMsg: 'WARNING',
QtCriticalMsg: 'CRITICAL',
QtFatalMsg: 'FATAL',
qt_api.QtDebugMsg: 'DEBUG',
qt_api.QtWarningMsg: 'WARNING',
qt_api.QtCriticalMsg: 'CRITICAL',
qt_api.QtFatalMsg: 'FATAL',
}
return cls._log_type_name_map[msg_type]

Expand Down
Loading