mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-07-30 07:03:01 +02:00
fix(connector): register the exit handler only when it is wired to aboutToQuit
This commit is contained in:
@@ -154,9 +154,16 @@ class BECConnector:
|
||||
logger.info("Shutting down BEC Client", repr(client))
|
||||
client.shutdown()
|
||||
|
||||
BECConnector.EXIT_HANDLERS[self.client] = terminate
|
||||
# In our GUI processes a QApplication always exists by this point (and a
|
||||
# QWidget-based connector could not even be constructed without one - Qt
|
||||
# aborts first). The guard is defensive for QObject-only connectors, which
|
||||
# Qt happily creates standalone, e.g. in headless tests or plugin code.
|
||||
# Record the handler only once it is actually wired: otherwise the
|
||||
# EXIT_HANDLERS entry would suppress the registration of a later connector
|
||||
# created when an application does exist, silently losing client teardown.
|
||||
app = QApplication.instance()
|
||||
if app is not None:
|
||||
BECConnector.EXIT_HANDLERS[self.client] = terminate
|
||||
app.aboutToQuit.connect(terminate)
|
||||
else:
|
||||
logger.warning(
|
||||
|
||||
@@ -207,8 +207,9 @@ def test_bec_connector_export_settings():
|
||||
|
||||
|
||||
def test_bec_connector_terminate_registration_no_qapp_instance(qtbot):
|
||||
"""Constructing a BECConnector before a QApplication exists must not raise; the exit
|
||||
handler is still registered, only the aboutToQuit wiring is skipped."""
|
||||
"""Constructing a BECConnector without a QApplication (possible for QObject-only
|
||||
connectors) must not raise, and must leave nothing registered: there is no
|
||||
aboutToQuit to wire, so the exit handler is not recorded either."""
|
||||
import bec_widgets.utils.bec_connector as m
|
||||
|
||||
fresh_client = mock.MagicMock(name="fresh_client")
|
||||
@@ -216,6 +217,29 @@ def test_bec_connector_terminate_registration_no_qapp_instance(qtbot):
|
||||
try:
|
||||
with mock.patch.object(m.QApplication, "instance", return_value=None):
|
||||
BECConnectorQObject(client=fresh_client) # must not raise
|
||||
assert fresh_client in BECConnector.EXIT_HANDLERS
|
||||
assert fresh_client not in BECConnector.EXIT_HANDLERS
|
||||
finally:
|
||||
BECConnector.EXIT_HANDLERS.pop(fresh_client, None)
|
||||
|
||||
|
||||
def test_bec_connector_terminate_registered_once_qapp_exists(qtbot):
|
||||
"""A connector created without a QApplication must not block the registration of a
|
||||
later connector for the same client: once an application exists, teardown is wired."""
|
||||
import bec_widgets.utils.bec_connector as m
|
||||
|
||||
fresh_client = mock.MagicMock(name="late_app_client")
|
||||
try:
|
||||
with mock.patch.object(m.QApplication, "instance", return_value=None):
|
||||
BECConnectorQObject(client=fresh_client)
|
||||
|
||||
# now an application exists (qtbot guarantees one) -> handler gets wired
|
||||
BECConnectorQObject(client=fresh_client)
|
||||
assert fresh_client in BECConnector.EXIT_HANDLERS
|
||||
|
||||
fresh_client.shutdown.reset_mock()
|
||||
QApplication.instance().aboutToQuit.emit()
|
||||
assert fresh_client.shutdown.called, "client teardown must run on aboutToQuit"
|
||||
finally:
|
||||
handler = BECConnector.EXIT_HANDLERS.pop(fresh_client, None)
|
||||
if handler is not None:
|
||||
QApplication.instance().aboutToQuit.disconnect(handler)
|
||||
|
||||
Reference in New Issue
Block a user