Skip to content

Commit

Permalink
Add warnings when function without dependencies is passed to ParamFun…
Browse files Browse the repository at this point in the history
…ction (#3545)

* Add warnings when function without dependencies is passed to ParamFunction/ParamMethod

* Simplify warning

* Remove ParamMethod warning
  • Loading branch information
philippjfr committed May 23, 2022
1 parent b6815b2 commit 7687d59
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
1 change: 1 addition & 0 deletions panel/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ async def wrapped(*wargs, **wkwargs):
def wrapped(*wargs, **wkwargs):
combined_args, combined_kwargs = combine_arguments(wargs, wkwargs)
return function(*combined_args, **combined_kwargs)
wrapped.__bound_function__ = function
return wrapped

__all__ = ["bind", "depends"]
34 changes: 23 additions & 11 deletions panel/param.py
Original file line number Diff line number Diff line change
Expand Up @@ -745,17 +745,16 @@ def _validate_object(self):
if not dependencies or not dependencies.get('watch'):
return
fn_type = 'method' if type(self) is ParamMethod else 'function'
self.param.warning(f"The {fn_type} supplied for Panel to display "
"was declared with `watch=True`, which will "
f"cause the {fn_type} to be called twice for "
"any change in a dependent Parameter. "
"`watch` should be False when Panel is "
"responsible for displaying the result "
f"of the {fn_type} call, while `watch=True` "
f"should be reserved for {fn_type}s that work "
"via side-effects, e.g. by modifying internal "
"state of a class or global state in an "
"application's namespace.")
self.param.warning(
f"The {fn_type} supplied for Panel to display was declared "
f"with `watch=True`, which will cause the {fn_type} to be "
"called twice for any change in a dependent Parameter. "
"`watch` should be False when Panel is responsible for "
f"displaying the result of the {fn_type} call, while "
f"`watch=True` should be reserved for {fn_type}s that work "
"via side-effects, e.g. by modifying internal state of a "
"class or global state in an application's namespace."
)

#----------------------------------------------------------------
# Callback API
Expand Down Expand Up @@ -878,6 +877,19 @@ class ParamFunction(ParamMethod):
def _link_object_params(self):
deps = getattr(self.object, '_dinfo', {})
dep_params = list(deps.get('dependencies', [])) + list(deps.get('kw', {}).values())
if not dep_params:
fn = getattr(self.object, '__bound_function__', self.object)
fn_name = getattr(fn, '__name__', repr(self.object))
self.param.warning(
f"The function {fn_name!r} does not have any dependencies "
"and will never update. Are you sure you did not intend "
"to depend on or bind a parameter or widget to this function? "
"If not simply call the function before passing it to Panel. "
"Otherwise, when passing a parameter as an argument, "
"ensure you pass at least one parameter and reference the "
"actual parameter object not the current value, i.e. use "
"object.param.parameter not object.parameter."
)
grouped = defaultdict(list)
for dep in dep_params:
grouped[id(dep.owner)].append(dep)
Expand Down

0 comments on commit 7687d59

Please sign in to comment.