jupyter-widgets / ipywidgets

Interactive Widgets for the Jupyter Notebook
https://ipywidgets.readthedocs.io
BSD 3-Clause "New" or "Revised" License
3.1k stars 946 forks source link

Rendering output from within async function does not work as intended #3901

Open and3rson opened 2 months ago

and3rson commented 2 months ago

Description

When modifying outputs from async functions, modifying components attributes (and doing prints) works, but re-rendering outputs does not.

Reproduce

Consider code which attempts to re-render the output from within async function:

%gui asyncio
import asyncio
import ipywidgets as widgets

buttons = widgets.Output()
lines = widgets.Output()

display(buttons, lines)

async def func():
    for i in range(5):
        # Render new button
        buttons.clear_output()
        with buttons:
            display(widgets.Button(description=str(i)))

        # Append new line
        with lines:
            print(i)

_ = asyncio.ensure_future(func())

This re-renders the button 5 times and prints 5 messages as expected: зображення

However, when adding a delay inside the function:

  ...
  async def func():
      for i in range(5):
+         await asyncio.sleep(0.1)

          # Render new button
          ...

...the button output never updates and gets stuck at initially rendered instance. However, prints still work fine: зображення

Expected behavior

with some_output: display(...) should always update UI, irregardless from where it was called from.

Context