Skip to content

Commit

Permalink
Ensure that ReplacementPane does not modify user objects
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Jan 19, 2020
1 parent 860ed2c commit bd0045b
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions panel/pane/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ def __init__(self, object=None, **params):
if p not in self.param}
super(ReplacementPane, self).__init__(object, **params)
self._pane = Pane(None)
self._internal = True
self._inner_layout = Row(self._pane, **{k: v for k, v in params.items() if k in Row.param})

def _update_pane(self, *events):
Expand All @@ -326,7 +327,10 @@ def _update_inner(self, new_object):
links = Link.registry.get(new_object)
except TypeError:
links = []
if type(self._pane) is pane_type and not links:

if type(self._pane) is pane_type and not links and self._internal:
# If the object has not external referrers we can update
# it inplace instead of replacing it
if isinstance(new_object, Reactive):
pvals = dict(self._pane.get_param_values())
new_params = {k: v for k, v in new_object.get_param_values()
Expand All @@ -338,8 +342,25 @@ def _update_inner(self, new_object):
# Replace pane entirely
kwargs = dict(self.get_param_values(), **self._kwargs)
del kwargs['object']
self._pane = Pane(new_object, **{k: v for k, v in kwargs.items()
if k in pane_type.param})
self._pane = panel(new_object, **{k: v for k, v in kwargs.items()
if k in pane_type.param})
if new_object is self._pane:
# If all watchers on the object are internal watchers
# we can make a clone of the object and update this
# clone going forward, otherwise we have replace the
# model entirely which is more expensive.
watch_fns = [
str(w.fn) for pwatchers in new_object._param_watchers.values()
for awatchers in pwatchers.values() for w in awatchers
]
if (all('Reactive._link_params' in wfn or 'PaneBase._update_pane' in wfn
for wfn in watch_fns) and not links):
self._pane = self._pane.clone()
self._internal = True
else:
self._internal = False
else:
self._internal = new_object is not self._pane
self._inner_layout[0] = self._pane

def _get_model(self, doc, root=None, parent=None, comm=None):
Expand Down

0 comments on commit bd0045b

Please sign in to comment.