I’m working on a complex application composed of several components. Each component can be a direct instance of param.Parameterized
or pn.viewable.Viewer
.
I’ve been able to create a simple example in order to show this weird behavior.
import panel as pn
import param
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
import numpy as np
pn.extension()
class Component(pn.viewable.Viewer):
sel = param.Selector(default="r1", objects=["r1", "r2"])
fig = param.ClassSelector(class_=figure)
m = param.Number(default=1, bounds=(0, 2))
def __init__(self, **params):
super().__init__(**params)
x = np.array([0, 1, 2, 3, 4])
y1 = self.m * x
y2 = -self.m * x
self.fig = figure(height=250)
r1 = self.fig.line(x, y1, line_color="red")
r2 = self.fig.line(x, y2, line_color="green")
r2.visible = False
@param.depends("sel", watch=True)
def _update_renderer_visibility(self):
idx = self.param.sel.objects.index(self.sel)
for i, r in enumerate(self.fig.renderers):
r.visible = i == idx
@param.depends("m", watch=True)
def _update_data(self):
x = self.fig.renderers[0].data_source.data["x"]
self.fig.renderers[0].data_source.data.update({
"y": self.m * x
})
self.fig.renderers[1].data_source.data.update({
"y": -self.m * x
})
def __panel__(self):
return pn.Column(
self.param.sel,
self.param.m,
self.fig,
)
template = pn.template.MaterialTemplate(
# main=Component()
main=pn.Column(Component())
)
template.show()
Note that when I created the template I used main=pn.Column(Component())
. This is because my application shows several components in a single column.
It seems like that this pn.Column
, causes the application to raise an error on the server side after I open the browser inspect tool, after which the application doesn’t work anymore: RuntimeError: _pending_writes should be non-None when we have a document lock, and we should have the lock when the document changes
.
Am I doing something wrong? Is this some kind of bug?
2025-04-29 13:43:31,009 ERROR: panel.reactive - Callback failed for object named 'Sel' changing property {'value': 'r2'}
Traceback (most recent call last):
File "/.venv/lib/python3.12/site-packages/panel/reactive.py", line 464, in _process_events
self.param.update(**self_params)
File "/.venv/lib/python3.12/site-packages/param/parameterized.py", line 2406, in update
restore = dict(self_._update(arg, **kwargs))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.12/site-packages/param/parameterized.py", line 2439, in _update
self_._batch_call_watchers()
File "/.venv/lib/python3.12/site-packages/param/parameterized.py", line 2624, in _batch_call_watchers
self_._execute_watcher(watcher, events)
File "/.venv/lib/python3.12/site-packages/param/parameterized.py", line 2586, in _execute_watcher
watcher.fn(*args, **kwargs)
File "/.venv/lib/python3.12/site-packages/panel/param.py", line 535, in link_widget
self.object.param.update(**{p_name: change.new})
File "/.venv/lib/python3.12/site-packages/param/parameterized.py", line 2406, in update
restore = dict(self_._update(arg, **kwargs))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.12/site-packages/param/parameterized.py", line 2439, in _update
self_._batch_call_watchers()
File "/.venv/lib/python3.12/site-packages/param/parameterized.py", line 2624, in _batch_call_watchers
self_._execute_watcher(watcher, events)
File "/.venv/lib/python3.12/site-packages/param/parameterized.py", line 2586, in _execute_watcher
watcher.fn(*args, **kwargs)
File "/.venv/lib/python3.12/site-packages/param/parameterized.py", line 767, in _sync_caller
return function()
^^^^^^^^^^
File "/.venv/lib/python3.12/site-packages/param/depends.py", line 85, in _depends
return func(*args, **kw)
^^^^^^^^^^^^^^^^^
File "/tmp/ipykernel_154213/1413694909.py", line 29, in _update_renderer_visibility
r.visible = i == idx
^^^^^^^^^
File "/.venv/lib/python3.12/site-packages/bokeh/core/has_props.py", line 336, in __setattr__
return super().__setattr__(name, value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.12/site-packages/bokeh/core/property/descriptors.py", line 332, in __set__
self._set(obj, old, value, setter=setter)
File "/.venv/lib/python3.12/site-packages/bokeh/core/property/descriptors.py", line 614, in _set
self._trigger(obj, old, value, hint=hint, setter=setter)
File "/.venv/lib/python3.12/site-packages/bokeh/core/property/descriptors.py", line 692, in _trigger
obj.trigger(self.name, old, value, hint, setter)
File "/.venv/lib/python3.12/site-packages/bokeh/model/model.py", line 583, in trigger
super().trigger(descriptor.name, old, new, hint=hint, setter=setter)
File "/.venv/lib/python3.12/site-packages/bokeh/util/callback_manager.py", line 177, in trigger
self.document.callbacks.notify_change(cast(Model, self), attr, old, new, hint, setter, invoke)
File "/.venv/lib/python3.12/site-packages/bokeh/document/callbacks.py", line 251, in notify_change
self.trigger_on_change(event)
File "/.venv/lib/python3.12/site-packages/bokeh/document/callbacks.py", line 423, in trigger_on_change
invoke_with_curdoc(doc, invoke_callbacks)
File "/.venv/lib/python3.12/site-packages/bokeh/document/callbacks.py", line 453, in invoke_with_curdoc
return f()
^^^
File "/.venv/lib/python3.12/site-packages/bokeh/document/callbacks.py", line 422, in invoke_callbacks
cb(event)
File "/.venv/lib/python3.12/site-packages/bokeh/document/callbacks.py", line 278, in <lambda>
self._change_callbacks[receiver] = lambda event: event.dispatch(receiver)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/.venv/lib/python3.12/site-packages/bokeh/document/events.py", line 352, in dispatch
super().dispatch(receiver)
File "/.venv/lib/python3.12/site-packages/bokeh/document/events.py", line 218, in dispatch
cast(DocumentPatchedMixin, receiver)._document_patched(self)
File "/.venv/lib/python3.12/site-packages/bokeh/server/session.py", line 244, in _document_patched
raise RuntimeError("_pending_writes should be non-None when we have a document lock, and we should have the lock when the document changes")
RuntimeError: _pending_writes should be non-None when we have a document lock, and we should have the lock when the document changes