From c9d1b7982d9d04d0f2a6e6822e3abd5998c2eee6 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 11 Nov 2026 19:43:42 +0000 Subject: [PATCH] test: retry Tk setup when tkinterdnd2 fails to load tkdnd tkinterdnd2 converts a failed 'package require tkdnd' into a plain RuntimeError('Unable to load tkdnd library.'). The existing three-attempt retry in the Tk test fixtures only caught tk.TclError, so one transient load failure on a Windows runner errored the test (master run 42625549084, Windows / Python 3.12: 253 passed, 1 error). Catch that specific RuntimeError in the same retry loop. Other RuntimeErrors are re-raised unchanged. Co-Authored-By: Claude Fable 5.2 Claude-Session: https://claude.ai/code/session_01THB2EyXE5J3ixR7k3GMr13 --- tests/test_collection_export_lifecycle.py | 6 +++++- tests/test_ui_accessibility.py | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/test_collection_export_lifecycle.py b/tests/test_collection_export_lifecycle.py index 4bf5dbf..8084c0c 100644 --- a/tests/test_collection_export_lifecycle.py +++ b/tests/test_collection_export_lifecycle.py @@ -33,7 +33,11 @@ def window(tmp_path, monkeypatch): try: ui = app.App() break - except app.tk.TclError: + except (app.tk.TclError, RuntimeError) as exc: + # tkinterdnd2 wraps a failed "package require tkdnd" in a plain + # RuntimeError; treat that like the transient TclError it hides. + if isinstance(exc, RuntimeError) and "tkdnd" not in str(exc): + raise partial = getattr(app.tk, "_default_root", None) if partial is not None: try: diff --git a/tests/test_ui_accessibility.py b/tests/test_ui_accessibility.py index fa7add5..1b1be8e 100644 --- a/tests/test_ui_accessibility.py +++ b/tests/test_ui_accessibility.py @@ -34,12 +34,16 @@ def setUp(self) -> None: self._second_doc = tmp_path / "Paper_Markierungen.pdf" self._second_doc.write_bytes(b"%PDF-1.4\n%%EOF\n") - last_error: tk.TclError | None = None + last_error: Exception | None = None for _attempt in range(3): try: self.app = DokuReader.App() break - except tk.TclError as exc: + except (tk.TclError, RuntimeError) as exc: + # tkinterdnd2 wraps a failed "package require tkdnd" in a + # plain RuntimeError; treat it like the TclError it hides. + if isinstance(exc, RuntimeError) and "tkdnd" not in str(exc): + raise last_error = exc partial_root = getattr(tk, "_default_root", None) if partial_root is not None: