Print output in widget callback not shown in notebook
ALL software version info
(this library, plus any other relevant software, e.g. bokeh, python, notebook, OS, browser, etc should be added within the dropdown below.)
Software Version Info
Panel 1.6.2
Jupyterlab 4.4.0
Python 13.3.3
Description of expected behavior and the observed behavior
It appears that the FileSelector widget can block certain dependencies, such as those including print() outputs, from occurring.
Complete, minimal, self-contained example code that reproduces the issue
In the below app, I’ve written a method _sync_params that just prints “done” whenever it’s called. With the param.depends decorator the way it is, I’d expect this to happen when either the button is pressed or the active file in the file chooser is changed.
But instead, “done” only appears when the button is pressed. Interacting with the file chooser doesn’t print anything, and furthermore even causes the button to stop working.
import panel as pn
from panel.viewable import Viewer
import param
pn.extension()
class TestChooser(Viewer):
def __init__(self, **params):
self._selector = pn.widgets.FileSelector()
self._button = pn.widgets.Button(name='Click')
super().__init__(**params)
self._layout = pn.Column(self._selector, self._button)
def __panel__(self):
return self._layout
@param.depends('_selector.value', '_button.value', watch=True)
def _sync_params(self):
print('done')
chooser = TestChooser()
chooser.servable()
It seems possible that the function is actually running, and just the print output is being blocked somehow.
In this second example, instead of printing, I update a counter each time the function runs. This example works as expected--each click of the button or change of the FileSelector value increments the count by one.
import panel as pn
from panel.viewable import Viewer
import param
pn.extension()
class TestChooser(Viewer):
count = param.Integer(default=0, doc='number of actions')
def __init__(self, **params):
self._selector = pn.widgets.FileSelector()
self._button = pn.widgets.Button(name='Click')
super().__init__(**params)
self._layout = pn.Column(
self._selector,
self._button,
pn.indicators.Number(value=self.param.count)
)
def __panel__(self):
return self._layout
@param.depends('_selector.value', '_button.value', watch=True)
def _sync_params(self):
self.count += 1
chooser = TestChooser()
chooser.servable()
This issue has been mentioned on HoloViz Discourse. There might be relevant details there:
https://discourse.holoviz.org/t/dependency-not-triggering-with-fileselector-widget/8689/7
Ah, I was about to close but then you mentioned this was in a notebook.
The problem isn't that the callback doesn't run but that the stdout isn't correctly intercepted and printed to the notebook cell.