Skip to content

LoadingIndicator stopped working from 0.80.2+ #5262

@yorevs

Description

@yorevs

Hello all,

After version 0.80.1 the LoadingIndicator of an Input component stopped working. This is the traceback:

/opt/homebrew/lib/python3.11/site-packages/textual/worker.py:368 in _run                                                                                                                                                                 │
│                                                                                                                                                                                                                                          │
│   365 │   │   │   self.state = WorkerState.RUNNING                                             ╭───────────────────────────────────────────────────── locals ─────────────────────────────────────────────────────╮                      │
│   366 │   │   │   app.log.worker(self)                                                         │           app = AskAiApp(title='AskAiApp', classes={'-dark-mode'}, pseudo_classes={'dark', 'focus'})             │                      │
│   367 │   │   │   try:                                                                         │         error = RuntimeError('no running event loop')                                                            │                      │
│ ❱ 368 │   │   │   │   self._result = await self.run()                                          │          self = <Worker ERROR name='ask_and_reply' description="ask_and_reply('what is the size of the Moon?')"> │                      │
│   369 │   │   │   except asyncio.CancelledError as error:                                      │     Traceback = <class 'rich.traceback.Traceback'>                                                               │                      │
│   370 │   │   │   │   self.state = WorkerState.CANCELLED                                       │ worker_failed = WorkerFailed("Worker raised exception: RuntimeError('no running event loop')")                   │                      │
│   371 │   │   │   │   self._error = error                                                      ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                      │
│                                                                                                                                                                                                                                          │
│ /opt/homebrew/lib/python3.11/site-packages/textual/worker.py:352 in run                                                                                                                                                                  │
│                                                                                                                                                                                                                                          │
│   349 │   │   Returns:                                                                         ╭──────────────────────────────────────────────── locals ─────────────────────────────────────────────────╮                               │
│   350 │   │   │   Return value of the work.                                                    │ self = <Worker ERROR name='ask_and_reply' description="ask_and_reply('what is the size of the Moon?')"> │                               │
│   351 │   │   """                                                                              ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯                               │
│ ❱ 352 │   │   return await (                                                                                                                                                                                                             │
│   353 │   │   │   self._run_threaded() if self._thread_worker else self._run_async()                                                                                                                                                     │
│   354 │   │   )                                                                                                                                                                                                                          │
│   355                                                                                                                                                                                                                                    │
│                                                                                                                                                                                                                                          │
│ /opt/homebrew/lib/python3.11/site-packages/textual/worker.py:324 in _run_threaded                                                                                                                                                        │
│                                                                                                                                                                                                                                          │
│   321 │   │                                                                                    ╭───────────────────────────────────────────────────── locals ─────────────────────────────────────────────────────╮                      │
│   322 │   │   loop = asyncio.get_running_loop()                                                │          loop = <_UnixSelectorEventLoop running=True closed=False debug=False>                                   │                      │
│   323 │   │   assert loop is not None                                                          │ run_awaitable = <function Worker._run_threaded.<locals>.run_awaitable at 0x375c4a700>                            │                      │
│ ❱ 324 │   │   return await loop.run_in_executor(None, runner, self._work)                      │  run_callable = <function Worker._run_threaded.<locals>.run_callable at 0x375c4b600>                             │                      │
│   325 │                                                                                        │ run_coroutine = <function Worker._run_threaded.<locals>.run_coroutine at 0x375c49620>                            │                      │
│   326 │   async def _run_async(self) -> ResultType:                                            │        runner = <function Worker._run_threaded.<locals>.run_callable at 0x375c4b600>                             │                      │
│   327 │   │   """Run an async worker.                                                          │          self = <Worker ERROR name='ask_and_reply' description="ask_and_reply('what is the size of the Moon?')"> │                      │
│                                                                                                ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                      │
│                                                                                                                                                                                                                                          │
│ /opt/homebrew/Cellar/python@3.11/3.11.9_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/thread.py:58 in run                                                                                                │
│                                                                                                                                                                                                                                          │
│    55 │   │   │   return                                                                       ╭── locals ───╮                                                                                                                           │
│    56 │   │                                                                                    │ self = None │                                                                                                                           │
│    57 │   │   try:                                                                             ╰─────────────╯                                                                                                                           │
│ ❱  58 │   │   │   result = self.fn(*self.args, **self.kwargs)                                                                                                                                                                            │
│    59 │   │   except BaseException as exc:                                                                                                                                                                                               │
│    60 │   │   │   self.future.set_exception(exc)                                                                                                                                                                                         │
│    61 │   │   │   # Break a reference cycle with the exception 'exc'                                                                                                                                                                     │
│                                                                                                                                                                                                                                          │
│ /opt/homebrew/lib/python3.11/site-packages/textual/worker.py:307 in run_callable                                                                                                                                                         │
│                                                                                                                                                                                                                                          │
│   304 │   │   def run_callable(work: Callable[[], ResultType]) -> ResultType:                                                                                                                                                            │
│   305 │   │   │   """Set the active worker, and call the callable."""                                                                                                                                                                    │
│   306 │   │   │   active_worker.set(self)                                                                                                                                                                                                │
│ ❱ 307 │   │   │   return work()                                                                                                                                                                                                          │
│   308 │   │                                                                                                                                                                                                                              │
│   309 │   │   if (                                                                                                                                                                                                                       │
│   310 │   │   │   inspect.iscoroutinefunction(self._work)                                                                                                                                                                                │
│                                                                                                                                                                                                                                          │
│ ╭───────────────────────────────────────────────────────────────────────────────────────────── locals ──────────────────────────────────────────────────────────────────────────────────────────────╮                                    │
│ │ self = <Worker ERROR name='ask_and_reply' description="ask_and_reply('what is the size of the Moon?')">                                                                                           │                                    │
│ │ work = functools.partial(<function AskAiApp.ask_and_reply at 0x36e1fb880>, AskAiApp(title='AskAiApp', classes={'-dark-mode'}, pseudo_classes={'dark', 'focus'}), 'what is the size of the Moon?') │                                    │
│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                                    │
│                                                                                                                                                                                                                                          │
│ /Users/hjunior/GIT-Repository/GitHub/askai/src/main/askai/tui/askai_app.py:373 in ask_and_reply                                                                                                                                          │
│                                                                                                                                                                                                                                          │
│   370 │   │   :param question: The question to ask the AI engine.                              ╭──────────────────────────────────────────── locals ─────────────────────────────────────────────╮                                       │
│   371 │   │   :return: A tuple containing a boolean indicating success or failure, and the AI' │ question = 'what is the size of the Moon?'                                                      │                                       │
│   372 │   │   """                                                                              │     self = AskAiApp(title='AskAiApp', classes={'-dark-mode'}, pseudo_classes={'dark', 'focus'}) │                                       │
│ ❱ 373 │   │   self.enable_controls(False)                                                      ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯                                       │
│   374 │   │   status, reply = self.askai.ask_and_reply(question)                                                                                                                                                                         │
│   375 │   │   self.enable_controls()                                                                                                                                                                                                     │
│   376                                                                                                                                                                                                                                    │
│                                                                                                                                                                                                                                          │
│ /Users/hjunior/GIT-Repository/GitHub/askai/src/main/askai/tui/askai_app.py:212 in enable_controls                                                                                                                                        │
│                                                                                                                                                                                                                                          │
│   209 │   │   :param enable: Whether to enable (True) or disable (False) the UI controls (defa ╭─────────────────────────────────────────── locals ────────────────────────────────────────────╮                                         │
│   210 │   │   """                                                                              │ enable = False                                                                                │                                         │
│   211 │   │   self.header.disabled = not enable                                                │   self = AskAiApp(title='AskAiApp', classes={'-dark-mode'}, pseudo_classes={'dark', 'focus'}) │                                         │
│ ❱ 212 │   │   self.line_input.loading = not enable                                             ╰───────────────────────────────────────────────────────────────────────────────────────────────╯                                         │
│   213 │   │   self.footer.disabled = not enable                                                                                                                                                                                          │
│   214 │                                                                                                                                                                                                                                  │
│   215 │   def activate_markdown(self) -> None:                                                                                                                                                                                           │
│                                                                                                                                                                                                                                          │
│ /opt/homebrew/lib/python3.11/site-packages/textual/widget.py:905 in _watch_loading                                                                                                                                                       │
│                                                                                                                                                                                                                                          │
│    902 │                                                                                        ╭───── locals ──────╮                                                                                                                    │
│    903 │   def _watch_loading(self, loading: bool) -> None:                                     │ loading = True    │                                                                                                                    │
│    904 │   │   """Called when the 'loading' reactive is changed."""                             │    self = Input() │                                                                                                                    │
│ ❱  905 │   │   self.set_loading(loading)                                                        ╰───────────────────╯                                                                                                                    │
│    906 │                                                                                                                                                                                                                                 │
│    907 │   ExpectType = TypeVar("ExpectType", bound="Widget")                                                                                                                                                                            │
│    908                                                                                                                                                                                                                                   │
│                                                                                                                                                                                                                                          │
│ /opt/homebrew/lib/python3.11/site-packages/textual/widget.py:899 in set_loading                                                                                                                                                          │
│                                                                                                                                                                                                                                          │
│    896 │   │   if loading:                                                                      ╭──────────────────────── locals ────────────────────────╮                                                                               │
│    897 │   │   │   loading_indicator = self.get_loading_widget()                                │                 loading = True                         │                                                                               │
│    898 │   │   │   loading_indicator.add_class(LOADING_INDICATOR_CLASS)                         │       loading_indicator = LoadingIndicator()           │                                                                               │
│ ❱  899 │   │   │   self._cover(loading_indicator)                                               │ LOADING_INDICATOR_CLASS = '-textual-loading-indicator' │                                                                               │
│    900 │   │   else:                                                                            │                    self = Input()                      │                                                                               │
│    901 │   │   │   self._uncover()                                                              ╰────────────────────────────────────────────────────────╯                                                                               │
│    902                                                                                                                                                                                                                                   │
│                                                                                                                                                                                                                                          │
│ /opt/homebrew/lib/python3.11/site-packages/textual/widget.py:648 in _cover                                                                                                                                                               │
│                                                                                                                                                                                                                                          │
│    645 │   │   self._uncover()                                                                  ╭────────── locals ───────────╮                                                                                                          │
│    646 │   │   self._cover_widget = widget                                                      │   self = Input()            │                                                                                                          │
│    647 │   │   widget._parent = self                                                            │ widget = LoadingIndicator() │                                                                                                          │
│ ❱  648 │   │   widget._start_messages()                                                         ╰─────────────────────────────╯                                                                                                          │
│    649 │   │   widget._post_register(self.app)                                                                                                                                                                                           │
│    650 │   │   self.app.stylesheet.apply(widget)                                                                                                                                                                                         │
│    651 │   │   self.refresh(layout=True)                                                                                                                                                                                                 │
│                                                                                                                                                                                                                                          │
│ /opt/homebrew/lib/python3.11/site-packages/textual/message_pump.py:500 in _start_messages                                                                                                                                                │
│                                                                                                                                                                                                                                          │
│   497 │   def _start_messages(self) -> None:                                                   ╭───────── locals ──────────╮                                                                                                             │
│   498 │   │   """Start messages task."""                                                       │ self = LoadingIndicator() │                                                                                                             │
│   499 │   │   if self.app._running:                                                            ╰───────────────────────────╯                                                                                                             │
│ ❱ 500 │   │   │   self._task = create_task(                                                                                                                                                                                              │
│   501 │   │   │   │   self._process_messages(), name=f"message pump {self}"                                                                                                                                                              │
│   502 │   │   │   )                                                                                                                                                                                                                      │
│   503 │   │   else:                                                                                                                                                                                                                      │
│                                                                                                                                                                                                                                          │
│ /opt/homebrew/Cellar/python@3.11/3.11.9_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/tasks.py:381 in create_task                                                                                                   │
│                                                                                                                                                                                                                                          │
│   378 │                                                                                        ╭───────────────────────────────── locals ──────────────────────────────────╮                                                             │
│   379 │   Return a Task object.                                                                │ context = None                                                            │                                                             │
│   380 │   """                                                                                  │    coro = <coroutine object MessagePump._process_messages at 0x36e71c130> │                                                             │
│ ❱ 381 │   loop = events.get_running_loop()                                                     │    name = 'message pump LoadingIndicator()'                               │                                                             │
│   382 │   if context is None:                                                                  ╰───────────────────────────────────────────────────────────────────────────╯                                                             │
│   383 │   │   # Use legacy API if context is not needed                                                                                                                                                                                  │
│   384 │   │   task = loop.create_task(coro)                                                                                                                                                                                              │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
RuntimeError: no running event loop

Setting loading = true in another context:

RuntimeError: Task <Task pending name='Task-1' coro=<App.run.<locals>.run_app() running at /opt/homebrew/lib/python3.11/site-packages/textual/app.py:2051> cb=[_run_until_complete_cb() at
/opt/homebrew/Cellar/python@3.11/3.11.9_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py:181]> got Future <_GatheringFuture pending> attached to a different loop

If I rollback to 0.80.1 it works again.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions