Repository: zauberzeug/nicegui

Issue #2744: Browser can't load page when table rows contain lists
Created: 2024-03-21T16:36:33Z
Description
As @rohitsathish noticed on #2697, the following minimal example causes the app to freeze:
ui.table(columns=[{'name': 'A', 'label': 'A', 'field': 'A'}], rows=[{'A': [1, 2, 3]}])
It's even more apparent when creating the table dynamically:
ui.button('Table', on_click=lambda: ui.table(columns=[{'name': 'A', 'label': 'A', 'field': 'A'}], rows=[{'A': [1, 2, 3]}]))
Somehow Vue and/or Quasar can't handle the row content. But a minimal Quasar app works with the same data:
<html>
  <head>
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" type="text/css" />
    <link href="https://cdn.jsdelivr.net/npm/quasar@2.15.1/dist/quasar.prod.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <div id="q-app">
      <q-table :columns="[{'name': 'A','label': 'A','field': 'A'}]" :rows="[{'A': [1, 2, 3]}]" row-key="id" />
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quasar@2.15.1/dist/quasar.umd.prod.js"></script>
    <script>
      const app = Vue.createApp({ setup() { return {}; } });
      app.use(Quasar);
      app.mount("#q-app");
    </script>
  </body>
</html>
I'm out of ideas. Can anyone help to find out what's going on? Thanks!

Duplicate issue #3653: uvloop goes crazy when ui.tab is given tuple as name
Created: 2024-08-30T12:41:06Z
Description
This is nothing critical, but it's very interesting behavior and it's really hard to diagnose - so I think it's worth putting here as an issue.
This code:
TN = ('Foo', 'Bar')

with ui.tabs() as tabs:
    ui.tab(TN)

ui.run(port=8888, reload=False)
locks completely after running - and after a lot of debugging I found that there's some infinite recursion in the internals of uvloop (so it's not even at the cpython level). If you debug this process with a C debugger (lldb in my case) you can see hundreds of thousands of stack frames looping somewhere in the uvlib:
  thread #4, name = 'python3'
    frame #0: 0x00007120381bd117 libc.so.6`__GI___futex_abstimed_wait_cancelable64 at futex-internal.c:57:12
    frame #1: 0x00007120381bd0e9 libc.so.6`__GI___futex_abstimed_wait_cancelable64 at futex-internal.c:87:9
    frame #2: 0x00007120381bd0e9 libc.so.6`__GI___futex_abstimed_wait_cancelable64(futex_word=0x0000712034407b6c, expected=0, clockid=<unavailable>, abstime=0x0000000000000000, private=<unavailable>) at futex-internal.c:139:10
    frame #3: 0x00007120381bfa41 libc.so.6`___pthread_cond_wait at pthread_cond_wait.c:503:10
    frame #4: 0x00007120381bf970 libc.so.6`___pthread_cond_wait(cond=0x0000712034407b40, mutex=0x0000712034407b00) at pthread_cond_wait.c:627:10
    frame #5: 0x00007120343a4689 loop.cpython-312-x86_64-linux-gnu.so`uv_cond_wait(cond=<unavailable>, mutex=<unavailable>) at thread.c:793:7
    frame #6: 0x0000712034407a90 loop.cpython-312-x86_64-linux-gnu.so`slow_io_pending_wq + 16
    frame #7: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #8: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #9: 0x0000712034407a90 loop.cpython-312-x86_64-linux-gnu.so`slow_io_pending_wq + 16
    frame #10: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #11: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #12: 0x0000712034407a90 loop.cpython-312-x86_64-linux-gnu.so`slow_io_pending_wq + 16
    frame #13: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #14: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #15: 0x0000712034407a90 loop.cpython-312-x86_64-linux-gnu.so`slow_io_pending_wq + 16
    frame #16: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #17: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #18: 0x0000712034407a90 loop.cpython-312-x86_64-linux-gnu.so`slow_io_pending_wq + 16
    frame #19: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    ...
  thread #5, name = 'python3'
    frame #0: 0x00007120381bd117 libc.so.6`__GI___futex_abstimed_wait_cancelable64 at futex-internal.c:57:12
    frame #1: 0x00007120381bd0e9 libc.so.6`__GI___futex_abstimed_wait_cancelable64 at futex-internal.c:87:9
    frame #2: 0x00007120381bd0e9 libc.so.6`__GI___futex_abstimed_wait_cancelable64(futex_word=0x0000712034407b68, expected=0, clockid=<unavailable>, abstime=0x0000000000000000, private=<unavailable>) at futex-internal.c:139:10
    frame #3: 0x00007120381bfa41 libc.so.6`___pthread_cond_wait at pthread_cond_wait.c:503:10
    frame #4: 0x00007120381bf970 libc.so.6`___pthread_cond_wait(cond=0x0000712034407b40, mutex=0x0000712034407b00) at pthread_cond_wait.c:627:10
    frame #5: 0x00007120343a4689 loop.cpython-312-x86_64-linux-gnu.so`uv_cond_wait(cond=<unavailable>, mutex=<unavailable>) at thread.c:793:7
    frame #6: 0x0000712034407a90 loop.cpython-312-x86_64-linux-gnu.so`slow_io_pending_wq + 16
    frame #7: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #8: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #9: 0x0000712034407a90 loop.cpython-312-x86_64-linux-gnu.so`slow_io_pending_wq + 16
    frame #10: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #11: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #12: 0x0000712034407a90 loop.cpython-312-x86_64-linux-gnu.so`slow_io_pending_wq + 16
    frame #13: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #14: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #15: 0x0000712034407a90 loop.cpython-312-x86_64-linux-gnu.so`slow_io_pending_wq + 16
    frame #16: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #17: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    frame #18: 0x0000712034407a90 loop.cpython-312-x86_64-linux-gnu.so`slow_io_pending_wq + 16
    frame #19: 0x0000712034407aa0 loop.cpython-312-x86_64-linux-gnu.so`run_slow_work_message + 16
    ...

(actual number of frames goes up to 600000 which I guess is just a limit for the debugger, and is repeating pattern of last 3 frames)
I have no idea why it happens, I found it when I mistakenly returned tuple instead of string as a tab name - but maybe by checking the variable type you can save a lot of debugging to some other lost soul ;-)

Closing comment (2024-09-02T08:38:36Z): Yes, digging deeper to find the root cause of this problem would be great.
Nevertheless, I'll close this issue as duplicate of #2744. Let's discuss possible steps forward over there.