pytest-dev / pytest-qt

pytest plugin for Qt (PyQt5/PyQt6 and PySide2/PySide6) application testing
https://pytest-qt.readthedocs.io
MIT License
409 stars 70 forks source link

Segfault on Ubuntu 22.04 #504

Closed hakonhagland closed 1 year ago

hakonhagland commented 1 year ago

I am on Ubuntu 22.04, using Poetry, Python 3.10 and PyQt6. When I run a test with pytest using the qtbot fixture I get a segmentation fault. If I remove the qtbot fixture from the test file, it works fine. Here is a minimal example (my real test case is more complicated):

$ poetry new --src myproject
$ cd myproject
$ poetry add pyqt6
$ poetry add --group=dev pytest
$ poetry add --group=dev pytest-qt
$ cat <<'END' > pytest.ini
[pytest]
qt_api=pyqt6
END
$ cat <<'END' > src/myproject/main.py
from PyQt6.QtWidgets import QApplication
def qapp(app: QApplication) -> None:  # This is the function that we will test with pytest
    app.quit()
END
$ cat <<'END' > tests/test_main.py  # This is the test file
import pytest
from PyQt6.QtWidgets import QApplication
import myproject.main
from typing import Any
QtBot = Any  # Missing type hints here
def test_app(qtbot: QtBot) -> None:
    app = QApplication([])
    myproject.main.qapp(app)
    assert 1 == 1
END
$ poetry install
$ poetry shell
$ pytest
============================================================================ test session starts ============================================================================
platform linux -- Python 3.10.4, pytest-7.4.0, pluggy-1.2.0
PyQt6 6.5.1 -- Qt runtime 6.5.1 -- Qt compiled 6.5.1
rootdir: /home/hakon/test/python/pytest-qt/qtbot/myproject
plugins: qt-4.2.0
collected 1 item                                                                                                                                                            

tests/test_main.py Fatal Python error: Segmentation fault

Current thread 0x00007f24e2fc1740 (most recent call first):
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/python.py", line 194 in pytest_pyfunc_call
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 80 in _multicall
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 112 in _hookexec
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 433 in __call__
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/python.py", line 1788 in runtest
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 169 in pytest_runtest_call
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 80 in _multicall
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 112 in _hookexec
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 433 in __call__
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 262 in <lambda>
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 341 in from_call
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 261 in call_runtest_hook
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 222 in call_and_report
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 133 in runtestprotocol
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/runner.py", line 114 in pytest_runtest_protocol
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 80 in _multicall
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 112 in _hookexec
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 433 in __call__
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/main.py", line 349 in pytest_runtestloop
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 80 in _multicall
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 112 in _hookexec
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 433 in __call__
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/main.py", line 324 in _main
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/main.py", line 270 in wrap_session
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/main.py", line 317 in pytest_cmdline_main
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_callers.py", line 80 in _multicall
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_manager.py", line 112 in _hookexec
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/pluggy/_hooks.py", line 433 in __call__
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/config/__init__.py", line 166 in main
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/lib/python3.10/site-packages/_pytest/config/__init__.py", line 189 in console_main
  File "/home/hakon/.cache/pypoetry/virtualenvs/myproject-rfHFWcwh-py3.10/bin/pytest", line 8 in <module>

Extension modules: PyQt6.QtCore, PyQt6.QtGui, PyQt6.QtWidgets, PyQt6.QtTest (total: 4)
Segmentation fault (core dumped)

Note: this question was first asked on stackoverflow.com

hakonhagland commented 1 year ago

Segmentation fault (core dumped)

I ran pytest with gdb to get a backtrace. The problem seems to be in the destructor ~QGuiApplication(). Here is a screen shot of the topmost frames:

image

The-Compiler commented 1 year ago

Qt does not support creating multiple QApplications in the same process. pytest-qt creates one for you when you use qtbot, which is why this doesn't work. I don't think there's anything pytest-qt could or should do about this.

hakonhagland commented 1 year ago

pytest-qt creates one for you when you use qtbot

@The-Compiler Thanks! This solved my issue!

I don't think there's anything pytest-qt could or should do about this.

I suggest maybe updating the docs? See PR #505 for an example that could reduce confusion for beginners.

mworion commented 10 months ago

Sorry to question again as I run through this issue as well. Interesting point is, that all my test went fine on PyQt5 (without segfault) and the issue started when moving to PyQt6. There was no change in using qtBot or generation a QApplication. Any ideas ? Many thanks in advance. Michel

Edit 2: I run the same test Suite on MacOS and Windows without any problems...

Here the segfault: It's the access to app.setTitel in line 78

tests/unit_tests/base/test_tpool.py ...Fatal Python error: Aborted

Current thread 0x00007f9a5732a740 (most recent call first):
  File "/opt/hostedtoolcache/Python/3.12.1/x64/lib/python3.12/site-packages/pytestqt/plugin.py", line 76 in qapp
  File "/opt/hostedtoolcache/Python/3.12.1/x64/lib/python3.12/site-packages/_pytest/fixtures.py", line 932 in call_fixture_func
  File "/opt/hostedtoolcache/Python/3.12.1/x64/lib/python3.12/site-packages/_pytest/fixtures.py", line 1126 in pytest_fixture_setup
  File "/opt/hostedtoolcache/Python/3.12.1/x64/lib/python3.12/site-packages/pluggy/_callers.py", line 77 in _multicall

Extension modules: PyQt6.QtCore, PyQt6.QtGui, PyQt6.QtWidgets, PyQt6.QtTest, zstandard.backend_c, charset_normalizer.md, numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, PyQt6.QtNetwork, erfa.ufunc (total: 21)
Aborted (core dumped)
Error: Process completed with exit code 134.