Skip to content

Commit 08f644e

Browse files
authored
Correct textual app execution to prevent stray log messages (#3344)
1 parent febcbc6 commit 08f644e

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

changes/3342.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
An incompatibility with Textual 3.0 that caused log messages to be generated on the console on app exit has been resolved.

textual/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ root = ".."
6666

6767
[tool.setuptools_dynamic_dependencies]
6868
dependencies = [
69-
"textual >= 0.44.0",
69+
"textual >= 3.0.0, < 4.0.0",
7070
"toga-core == {version}",
7171
]
7272

textual/src/toga_textual/app.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import threading
23

34
import toga
45
from textual.app import App as TextualApp
@@ -27,6 +28,7 @@ def __init__(self, interface):
2728
self.interface._impl = self
2829

2930
self.loop = asyncio.new_event_loop()
31+
asyncio.set_event_loop(self.loop)
3032
self.native = TogaApp(self)
3133

3234
self._current_window = None
@@ -56,7 +58,21 @@ def exit(self):
5658
self.native.exit()
5759

5860
def main_loop(self):
59-
self.loop.run_until_complete(self.native.run_async(headless=self.headless))
61+
# This is duplicating the bulk of TextualApp.run(); however, that entry point
62+
# doesn't give any control over the event loop that is used. The key detail
63+
# is that the _context() is required to capture logging messages generated
64+
# as the app is shutting down. See textualize/textual#5091.
65+
with self.native._context():
66+
try:
67+
self.native._loop = self.loop
68+
self.native._thread_id = threading.get_ident()
69+
70+
self.loop.run_until_complete(
71+
self.native.run_async(headless=self.headless)
72+
)
73+
finally:
74+
self.native._loop = None
75+
self.native._thread_id = 0
6076

6177
def set_icon(self, icon):
6278
pass

0 commit comments

Comments
 (0)