pn.serve with `threaded=True` does not work in Python 3.12
ALL software version info
bokeh 3.3.4
panel 1.3.8
param 2.0.2
python 3.12.2
Description of expected behavior and the observed behavior
It appears as tho the pn.serve(... ,threaded=True) option does not work in python 3.12.2. See the error message below. As far as i can tell the app doesn't matter, this was just some test app i had handy to demonstrate the bug.
I'm not sure i actually need this feature, but i'm sharing it since it took me a little bit to debug when upgrading an old app to python 3.12.
Complete, minimal, self-contained example code that reproduces the issue
"""threaded bug on py 3.12"""
import panel as pn
class App:
def __init__(self) -> None:
self.tabs = pn.Tabs(
dynamic=True,
tabs_location="left",
css_classes=["tabs-left"],
align="center",
sizing_mode="stretch_width",
)
self.tabs.param.watch(self.update_active_tabs, ["active"])
def build_tabs(self, event):
tab1_thing = pn.pane.Markdown("# Tab 1 thing. Name=Tab1", name="Tab1")
tab2_thing = pn.pane.Markdown("# Tab 2 thing. Name=Tab2", name="Tab2")
self.tabs[:] = [("Tab 1 Alt Name", tab1_thing), ("Tab 2 Alt Name", tab2_thing)]
def update_active_tabs(self, event):
name = self.tabs.objects[self.tabs.active].name
print(name)
def main():
app = App()
button = pn.widgets.Button(name="Build tabs")
button.on_click(app.build_tabs)
col = pn.Column(app.tabs, button)
col.servable()
return col
app = pn.serve(main, threaded=True)
Stack traceback and/or browser JavaScript console output
Launching server at http://localhost:56947
Task exception was never retrieved
future: <Task finished name='Task-1' coro=<SelectorThread.__init__.<locals>.thread_manager_anext() done, defined at c:\Users\...\CCG\ccg\.venv312\Lib\site-packages\tornado\platform\asyncio.py:462> exception=RuntimeError("can't create new thread at interpreter shutdown")>
Traceback (most recent call last):
File "c:\Users\...\CCG\ccg\.venv312\Lib\site-packages\tornado\platform\asyncio.py", line 465, in thread_manager_anext
await self._thread_manager_handle.__anext__()
File "c:\Users\...\CCG\ccg\.venv312\Lib\site-packages\tornado\platform\asyncio.py", line 511, in _thread_manager
self._thread.start()
File "C:\Users\...\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 992, in start
_start_new_thread(self._bootstrap, ())
File "C:\Users\...\CCG\debugpy\debugpy\src\debugpy\_vendored\pydevd\_pydev_bundle\pydev_monkey.py", line 1114, in pydev_start_new_thread
return _original_start_new_thread(_UseNewThreadStartup(function, args, kwargs), ())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: can't create new thread at interpreter shutdown
This seems very surprising, a significant fraction of our test suite uses a threaded server to run the tests.
This appears to be a CPython bug/regression, see https://github.com/python/cpython/issues/113964. I think the solution for now is to add a time.sleep after starting the thread to ensure the thread is fully running before Python attempts to shut down.
Any updates? I remembered why i needed threaded=True, #3601