Skip to content

Commit

Permalink
Fix potential size changed during iteration errors (#7131)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr authored Aug 11, 2024
1 parent 52335a1 commit 395dbce
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 19 deletions.
2 changes: 1 addition & 1 deletion panel/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ async def _watch_esm(self):

def _update_esm(self):
esm = self._render_esm()
for ref, (model, _) in self._models.items():
for ref, (model, _) in self._models.copy().items():
if esm == model.esm:
continue
self._apply_update({}, {'esm': esm}, model, ref)
Expand Down
4 changes: 2 additions & 2 deletions panel/pane/echarts.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def on_event(self, event: str, callback: Callable, query: str | None = None):
"""
self._py_callbacks[event][query].append(callback)
event_config = {event: list(queries) for event, queries in self._py_callbacks.items()}
for ref, (model, _) in self._models.items():
for ref, (model, _) in self._models.copy().items():
self._apply_update({}, {'event_config': event_config}, model, ref)

def js_on_event(self, event: str, callback: str | CustomJS, query: str | None = None, **args):
Expand All @@ -176,7 +176,7 @@ def js_on_event(self, event: str, callback: str | CustomJS, query: str | None =
of the object.
"""
self._js_callbacks[event].append((query, callback, args))
for ref, (model, _) in self._models.items():
for ref, (model, _) in self._models.copy().items():
js_events = self._get_js_events(ref)
self._apply_update({}, {'js_events': js_events}, model, ref)

Expand Down
2 changes: 1 addition & 1 deletion panel/pane/plotly.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def _send_update_msg(
msg['relayout'] = relayout_data
if restyle_data:
msg['restyle'] = {'data': restyle_data, 'traces': trace_indexes}
for ref, (m, _) in self._models.items():
for ref, (m, _) in self._models.copy().items():
self._apply_update([], msg, m, ref)

def _update_from_figure(self, event, *args, **kwargs):
Expand Down
14 changes: 7 additions & 7 deletions panel/reactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ def _manual_update(
"""

def _update_manual(self, *events: param.parameterized.Event) -> None:
for ref, (model, parent) in self._models.items():
for ref, (model, parent) in self._models.copy().items():
if ref not in state._views or ref in state._fake_roots:
continue
viewable, root, doc, comm = state._views[ref]
Expand Down Expand Up @@ -927,7 +927,7 @@ def _send_event(self, Event: ModelEvent, **event_kwargs):
Event(model=model, **event_kwargs)
"""
for ref, (model, _) in self._models.items():
for ref, (model, _) in self._models.copy().items():
if ref not in state._views or ref in state._fake_roots:
continue
event = Event(model=model, **event_kwargs)
Expand Down Expand Up @@ -1029,7 +1029,7 @@ def _update_cds(self, *events: param.parameterized.Event) -> None:
self._processed, self._data = self._get_data()
msg = {'data': self._data}
named_events = {event.name: event for event in events}
for ref, (m, _) in self._models.items():
for ref, (m, _) in self._models.copy().items():
self._apply_update(named_events, msg, m.source, ref)

@updating
Expand All @@ -1039,7 +1039,7 @@ def _update_selected(
indices = self.selection if indices is None else indices
msg = {'indices': indices}
named_events = {event.name: event for event in events}
for ref, (m, _) in self._models.items():
for ref, (m, _) in self._models.copy().items():
self._apply_update(named_events, msg, m.source.selected, ref)

def _apply_stream(self, ref: str, model: Model, stream: 'DataDict', rollover: Optional[int]) -> None:
Expand All @@ -1052,7 +1052,7 @@ def _apply_stream(self, ref: str, model: Model, stream: 'DataDict', rollover: Op
@updating
def _stream(self, stream: 'DataDict', rollover: Optional[int] = None) -> None:
self._processed, _ = self._get_data()
for ref, (m, _) in self._models.items():
for ref, (m, _) in self._models.copy().items():
if ref not in state._views or ref in state._fake_roots:
continue
viewable, root, doc, comm = state._views[ref]
Expand All @@ -1074,7 +1074,7 @@ def _apply_patch(self, ref: str, model: Model, patch: 'Patches') -> None:

@updating
def _patch(self, patch: 'Patches') -> None:
for ref, (m, _) in self._models.items():
for ref, (m, _) in self._models.copy().items():
if ref not in state._views or ref in state._fake_roots:
continue
viewable, root, doc, comm = state._views[ref]
Expand Down Expand Up @@ -2176,7 +2176,7 @@ def on_event(self, node: str, event: str, callback: Callable) -> None:
f"nodes include: {self._parser.nodes}.")
self._event_callbacks[node][event].append(callback)
events = self._get_events()
for ref, (model, _) in self._models.items():
for ref, (model, _) in self._models.copy().items():
self._apply_update({}, {'events': events}, model, ref)

__all__ = (
Expand Down
2 changes: 1 addition & 1 deletion panel/widgets/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def snapshot(self):
Triggers a snapshot of the current VideoStream state to sync
the widget value.
"""
for ref, (m, _) in self._models.items():
for ref, (m, _) in self._models.copy().items():
m.snapshot = not m.snapshot
(self, root, doc, comm) = state._views[ref]
if comm and 'embedded' not in root.tags:
Expand Down
14 changes: 7 additions & 7 deletions panel/widgets/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ def _update_cds(self, *events: param.parameterized.Event):
self._update_index_mapping()
self._data = {k: _convert_datetime_array_ignore_list(v) for k, v in data.items()}
msg = {'data': self._data}
for ref, (m, _) in self._models.items():
for ref, (m, _) in self._models.copy().items():
self._apply_update(events, msg, m.source, ref)

def _process_param_change(self, params):
Expand Down Expand Up @@ -1503,7 +1503,7 @@ def _get_selectable(self):
def _update_style(self, recompute=True):
styles = self._get_style_data(recompute)
msg = {'cell_styles': styles}
for ref, (m, _) in self._models.items():
for ref, (m, _) in self._models.copy().items():
self._apply_update([], msg, m, ref)

def _get_children(self):
Expand Down Expand Up @@ -1567,7 +1567,7 @@ def _update_children(self, *events):
elif event.name == 'row_content':
self._indexed_children.clear()
self._child_panels, removed, expanded = self._get_children()
for ref, (m, _) in self._models.items():
for ref, (m, _) in self._models.copy().items():
root, doc, comm = state._views[ref][1:]
for child_panel in removed:
child_panel._cleanup(root)
Expand All @@ -1591,7 +1591,7 @@ def _stream(self, stream, rollover=None, follow=True):
self._update_index_mapping()

def stream(self, stream_value, rollover=None, reset_index=True, follow=True):
for ref, (model, _) in self._models.items():
for ref, (model, _) in self._models.copy().items():
self._apply_update([], {'follow': follow}, model, ref)
super().stream(stream_value, rollover, reset_index)
if follow and self.pagination:
Expand Down Expand Up @@ -1649,7 +1649,7 @@ def _update_cds(self, *events):

def _update_selectable(self):
selectable = self._get_selectable()
for ref, (model, _) in self._models.items():
for ref, (model, _) in self._models.copy().items():
self._apply_update([], {'selectable_rows': selectable}, model, ref)

@param.depends('page_size', watch=True)
Expand All @@ -1658,7 +1658,7 @@ def _update_max_page(self):
nrows = self.page_size or self.initial_page_size
max_page = max(length//nrows + bool(length%nrows), 1)
self.param.page.bounds = (1, max_page)
for ref, (model, _) in self._models.items():
for ref, (model, _) in self._models.copy().items():
self._apply_update([], {'max_page': max_page}, model, ref)

def _clear_selection_remote_pagination(self, event):
Expand Down Expand Up @@ -2035,7 +2035,7 @@ def download(self, filename: str = 'table.csv'):
filename: str
The filename to save the table as.
"""
for ref, (model, _) in self._models.items():
for ref, (model, _) in self._models.copy().items():
self._apply_update({}, {'filename': filename}, model, ref)
self._apply_update({}, {'download': not model.download}, model, ref)

Expand Down

0 comments on commit 395dbce

Please sign in to comment.