Resolve "ci pipelines crash (more often than not) with segfaults"
Description
This MR identify and fix causes of segfaults.
The main reason why we had segfaults in general: no xvfb installed on the Docker image. Xvfb, together with pytest-xvfb (which I already included before), allows to "display" X11 windows offscreen. This is the main difference between the test environment and tests on our computers.
Another great cause of segfaults was: a QApplication
is required, always - apparently
it was missing for some tests, so I added an autouse fixture from pytest-qt
. Normally
tests using qtbot
have a QApplication
from qtbot
, but it causes no harm to put
belt and braces and add a QApplication
.
The main reason of systematic, recent PyQt tests failures was: the metaclass (__new__
)
and inheritance of QObject
in error_popups.py
(always failing on my computer),
and also not resetting the Singleton.
I replaced that with a classic old-style way of doing a singleton. That said, there
are too much singletons in BEC in general (why ?), and mixins as well. At least for BEC Widgets,
multiple inheritance can be harmful, as well as inheriting from C++ objects (as we have seen
before).
Finally, PySide is very sensitive to exceptions in slots (one exception -> one segfault),
and to parameters expected by slots... Apparently it messes up with Python to call the
slot even if the function is missing some (normally expected) parameters from the Signal.
So, I replaced all Slot
by SafeSlot
, which ensures an exception would be printed
instead of raising. I added parameters in some slots from pyqtgraph.
Since I did this I get errors like:
ERROR tests/unit_tests/test_bec_dock.py::test_add_remove_bec_figure_to_dock - TypeError: QWidgetAction(parent: Optional[QObject]): not enough arguments
which would have probably produced a segfault before (
Note: reading comments about PyQt/PySide crashes, I found many reports of
setStyleSheet
causing segfaults. First I disabled those, but I re-enabled them because
I didn't see any difference... Since, my advice would be:
- to not change style in
__init__
- hence, not from
set_config()
which should be renamedset_state()
IMO- moreover, the choice of theme is purely something for the client, so why saving this config/state ?
- hence, not from
-
BECFigure
should not havechange_theme
, because the theme is not something of a particular widget, it is applied to the whole application - better to call it once, depending on user preference, rather than changing theme too often
Closes #271 (closed)