Skip to content

provide App.arun() that does everything run does, but async #5750

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 43 additions & 21 deletions src/textual/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2115,34 +2115,56 @@ def run(
Returns:
App return value.
"""

async def run_app() -> None:
"""Run the app."""
self._loop = asyncio.get_running_loop()
self._thread_id = threading.get_ident()
with self._context():
try:
await self.run_async(
headless=headless,
inline=inline,
inline_no_clear=inline_no_clear,
mouse=mouse,
size=size,
auto_pilot=auto_pilot,
)
finally:
self._loop = None
self._thread_id = 0

if _ASYNCIO_GET_EVENT_LOOP_IS_DEPRECATED:
# N.B. This doesn't work with Python<3.10, as we end up with 2 event loops:
asyncio.run(run_app())
return asyncio.run(self.arun())
else:
# However, this works with Python<3.10:
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(run_app())
return event_loop.run_until_complete(self.arun())
return self.return_value

def arun(
self,
*,
headless: bool = False,
inline: bool = False,
inline_no_clear: bool = False,
mouse: bool = True,
size: tuple[int, int] | None = None,
auto_pilot: AutopilotCallbackType | None = None,
) -> ReturnType | None:
"""Run the app.

Args:
headless: Run in headless mode (no output).
inline: Run the app inline (under the prompt).
inline_no_clear: Don't clear the app output when exiting an inline app.
mouse: Enable mouse support.
size: Force terminal size to `(WIDTH, HEIGHT)`,
or None to auto-detect.
auto_pilot: An auto pilot coroutine.

Returns:
App return value.
"""
self._loop = asyncio.get_running_loop()
self._thread_id = threading.get_ident()
with self._context():
try:
await self.run_async(
headless=headless,
inline=inline,
inline_no_clear=inline_no_clear,
mouse=mouse,
size=size,
auto_pilot=auto_pilot,
)
return self.return_value
finally:
self._loop = None
self._thread_id = 0

async def _on_css_change(self) -> None:
"""Callback for the file monitor, called when CSS files change."""
css_paths = (
Expand Down