From 7c6cda681c47cd1f52f0e3da66f9f79f0f3de13d Mon Sep 17 00:00:00 2001 From: Mirko Holler Date: Tue, 20 Oct 2026 15:12:51 +0200 Subject: [PATCH] test(xrayeye): keep the ellipse-ROI test items in a module-lifetime QGraphicsScene Unparented pyqtgraph ROIs could be garbage-collected while the next ROI was being built, which crashed PySide6 in CI with --random-order (segfault in GraphicsObject.itemChange during garbage collection). Test logic unchanged. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01TNtKEk4jAyjebMDQFwRHJQ --- .../test_x_ray_eye_ellipse_roi.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/tests_bec_widgets/test_x_ray_eye_ellipse_roi.py b/tests/tests_bec_widgets/test_x_ray_eye_ellipse_roi.py index e07ece3b..b16ad85b 100644 --- a/tests/tests_bec_widgets/test_x_ray_eye_ellipse_roi.py +++ b/tests/tests_bec_widgets/test_x_ray_eye_ellipse_roi.py @@ -27,6 +27,22 @@ def _qapp(): return pg.mkQApp() +# All test ROIs go into one scene that lives for the whole module: Qt then owns the items, and the +# Python garbage collector cannot delete an unparented ROI while the next one is being built (that +# crashed PySide6 / pyqtgraph in CI with --random-order: "Fatal Python error: Segmentation fault" in +# GraphicsObject.itemChange during garbage collection). +_SCENE = None + + +@pytest.fixture(autouse=True, scope="module") +def _scene(_qapp): + global _SCENE + _SCENE = pg.QtWidgets.QGraphicsScene() + yield _SCENE + _SCENE.clear() + _SCENE = None + + class _FakeEllipticalROI(pg.EllipseROI): """pg ellipse standing in for bec_widgets' EllipticalROI in isinstance checks.""" @@ -39,6 +55,7 @@ def _patch_roi_class(): def _roi(pos=(10.0, 20.0), size=(40.0, 20.0), angle=0.0): roi = _FakeEllipticalROI(pos, size, angle=angle) + _SCENE.addItem(roi) return roi