From 8f52639d14997929eeb4f9e1b9a1be80928531f1 Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Sun, 16 Aug 2026 07:01:04 +0200 Subject: [PATCH] lib.App: Restore caller's event loop in run() run() remembers the thread's current event loop before creating a new one only when the app does not own a loop yet. The finally block, however, always restores the remembered loop or unsets the loop when there was none. So when a caller passes its own event loop to the App constructor and has set it as the thread's current loop, run() unsets the thread's loop on the way out, although it never changed it. Remember the thread's current event loop unconditionally and restore it in the finally block; for a caller-provided loop that is a no-op. Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.84.2 Signed-off-by: Jan Lindemann --- src/python/jw/pkg/lib/App.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/python/jw/pkg/lib/App.py b/src/python/jw/pkg/lib/App.py index a0febcc7..858c7666 100644 --- a/src/python/jw/pkg/lib/App.py +++ b/src/python/jw/pkg/lib/App.py @@ -513,9 +513,8 @@ class App: # export return self.__parser def run(self, argv: list[str] | None = None) -> None: - previous_eloop: asyncio.AbstractEventLoop | None = None + previous_eloop = _get_current_event_loop() if self.__eloop is None: - previous_eloop = _get_current_event_loop() eloop = asyncio.new_event_loop() asyncio.set_event_loop(eloop) self.__eloop = eloop