Search code examples
pythonpytestpytest-qt

Why a Fatal Python error when testing using pytest-qt?


My first test using pytest-qt failed immediately with a Fatal Python error. I reduced the code to this (a test that would never pass, but shouldn't crash):

from PyQt5 import QtCore as qtc


class sut(qtc.QObject):
    sig_sig_sputnik = qtc.pyqtSignal()

    def __init__(self):
        super().__init__()

    def listen(self):
        pass


def test_emit(qtbot):
    uut = sut()
    with qtbot.waitSignal(sut.sig_sig_sputnik, raising=True):
        uut.listen()

Executing this fails with:

=== test session starts ====
platform linux -- Python 3.6.9, pytest-5.4.3, py-1.8.1, pluggy-0.13.1
PyQt5 5.10.1 -- Qt runtime 5.12.9 -- Qt compiled 5.9.5
rootdir: [~]/src/npsw/frameworks/rtx, inifile: pytest.ini
plugins: qt-3.3.0, metadata-1.10.0, html-2.1.1, jnj-radish-1.4.0
collected 1 item                                                                                                                                                             

test_min.py Fatal Python error: Aborted

Current thread 0x00007f7c8411c740 (most recent call first):
  File "[~]/.local/lib/python3.6/site-packages/pytestqt/plugin.py", line 57 in qapp
  File "[~]/.local/lib/python3.6/site-packages/_pytest/fixtures.py", line 792 in call_fixture_func
  File "[~]/.local/lib/python3.6/site-packages/_pytest/fixtures.py", line 964 in pytest_fixture_setup
[boilerplate pytest stack from here on down]

Note that the failure occurs in the qapp fixture, but the test is using qtbot (which uses qapp itself).

I recognize there is a mismatch among the versions shown for PyQt5, Qt runtime, and Qt compiled (in the second line of the output). My 18.04 Ubuntu system has Qt5.9 as the systemwide Qt (from the standard bionic PPA), but the development group is using 5.12. The 5.12 runtimes are installed to a particular location, and for this run, LD_LIBRARY_PATH points to that location. If I do not use this setting, a different error occurs before pytest even starts to run:

INTERNALERROR> ImportError: /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5: symbol _ZNK15QDateTimeParser5parseER7QStringRiRK9QDateTimeb version Qt_5_PRIVATE_API not defined in file libQt5Core.so.5 with link time reference


Solution

  • Unsurprisingly, there is a configuration issue with the Qt5.12 libraries simply being copied into a folder. I was able to craft a workaround as follows:

    sudo mkdir /usr/bin/platforms
    sudo ln -s /our/local/libqxcb.so /usr/bin/platforms/libqxcb.so
    

    This was sufficient for me to run my tests without this crash.

    As Florian at the pytest-qt site advised me, this Python:

    from PyQt5.QtWidgets import QApplication
    app = QApplication([])
    

    also fails, but without much information. Then I got a tip to

    export QT_DEBUG_PLUGINS=1
    

    and the extra diagnostic info pointed me to that platforms folder.