Skip to content

Commit

Permalink
Allow ParamMethod and ParamFunction to be lazy
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Feb 6, 2021
1 parent 50926d3 commit f6e2572
Showing 1 changed file with 19 additions and 9 deletions.
28 changes: 19 additions & 9 deletions panel/param.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,12 +644,17 @@ class ParamMethod(ReplacementPane):
return any object which itself can be rendered as a Pane.
"""

lazy = param.Boolean(default=False, doc="""
Whether to lazily evaluate the contents of the object
only when it is required for rendering.""")

def __init__(self, object=None, **params):
super().__init__(object, **params)
self._evaled = not self.lazy
self._link_object_params()
if object is not None:
self._validate_object()
self._update_inner(self.eval(object))
self._replace_pane(not self.lazy)

@param.depends('object', watch=True)
def _validate_object(self):
Expand Down Expand Up @@ -684,6 +689,12 @@ def eval(self, function):
kwargs = {n: getattr(dep.owner, dep.name) for n, dep in kw_deps.items()}
return function(*args, **kwargs)

def _replace_pane(self, *args, force=False):
self._evaled = bool(self._models) or force or not self.lazy
if self._evaled:
new_object = self.eval(self.object)
self._update_inner(new_object)

def _update_pane(self, *events):
callbacks = []
for watcher in self._callbacks:
Expand All @@ -694,8 +705,7 @@ def _update_pane(self, *events):
obj.param.unwatch(watcher)
self._callbacks = callbacks
self._link_object_params()
if object is not None:
self._update_inner(self.eval(self.object))
self._replace_pane()

def _link_object_params(self):
parameterized = get_method_owner(self.object)
Expand Down Expand Up @@ -726,8 +736,7 @@ def update_pane(*events):
self._callbacks.append(watcher)
for p in params:
deps.append(p)
new_object = self.eval(self.object)
self._update_inner(new_object)
self._replace_pane()

for _, params in full_groupby(params, lambda x: (x.inst or x.cls, x.what)):
p = params[0]
Expand All @@ -736,6 +745,11 @@ def update_pane(*events):
watcher = pobj.param.watch(update_pane, ps, p.what)
self._callbacks.append(watcher)

def _get_model(self, doc, root=None, parent=None, comm=None):
if not self._evaled:
self._replace_pane(force=True)
return super()._get_model(doc, root, parent, comm)

#----------------------------------------------------------------
# Public API
#----------------------------------------------------------------
Expand All @@ -757,10 +771,6 @@ class ParamFunction(ParamMethod):

priority = 0.6

def _replace_pane(self, *args):
new_object = self.eval(self.object)
self._update_inner(new_object)

def _link_object_params(self):
deps = self.object._dinfo
dep_params = list(deps['dependencies']) + list(deps.get('kw', {}).values())
Expand Down

0 comments on commit f6e2572

Please sign in to comment.