From 2aca2f779e05a1eaa15fab3b6c72da38a49391ad Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Mon, 25 Sep 2023 15:10:52 +0200 Subject: [PATCH] Handle parameter references from Param 2.0 (#5906) --- holoviews/core/spaces.py | 8 ++++++-- holoviews/core/util.py | 7 ++++++- holoviews/streams.py | 20 +++++++++++++++----- holoviews/tests/util/test_transform.py | 2 +- holoviews/util/__init__.py | 2 +- 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/holoviews/core/spaces.py b/holoviews/core/spaces.py index 22298db4b8..83930331e0 100644 --- a/holoviews/core/spaces.py +++ b/holoviews/core/spaces.py @@ -459,7 +459,7 @@ class Callable(param.Parameterized): """ callable = param.Callable(default=None, constant=True, doc=""" - The callable function being wrapped.""") + The callable function being wrapped.""", **util.disallow_refs) inputs = param.List(default=[], constant=True, doc=""" The list of inputs the callable function is wrapping. Used @@ -546,6 +546,8 @@ def __call__(self, *args, **kwargs): # Nothing to do for callbacks that accept no arguments kwarg_hash = kwargs.pop('_memoization_hash_', ()) (self.args, self.kwargs) = (args, kwargs) + if hasattr(self.callable, 'rx'): + return self.callable.rx.resolve() if not args and not kwargs and not any(kwarg_hash): return self.callable() inputs = [i for i in self.inputs if isinstance(i, DynamicMap)] streams = [] @@ -772,7 +774,9 @@ def __init__(self, callback, initial_items=None, streams=None, **params): streams = streams_list_from_dict(streams) # If callback is a parameterized method and watch is disabled add as stream - if (params.get('watch', True) and (util.is_param_method(callback, has_deps=True) or + if util.param_version > util.Version('2.0.0rc1') and param.parameterized.resolve_ref(callback): + streams.append(callback) + elif (params.get('watch', True) and (util.is_param_method(callback, has_deps=True) or (isinstance(callback, FunctionType) and hasattr(callback, '_dinfo')))): streams.append(callback) diff --git a/holoviews/core/util.py b/holoviews/core/util.py index 21876175dd..4ae9f1c0d4 100644 --- a/holoviews/core/util.py +++ b/holoviews/core/util.py @@ -43,6 +43,8 @@ anonymous_dimension_label = '_' +disallow_refs = {'allow_refs': False} if param_version > Version('2.0.0rc1') else {} + # Argspec was removed in Python 3.11 ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') @@ -1617,7 +1619,10 @@ def resolve_dependent_value(value): from panel.depends import param_value_if_widget from panel.widgets import RangeSlider range_widget = isinstance(value, RangeSlider) - value = param_value_if_widget(value) + if param_version > Version('2.0.0rc1'): + value = param.parameterized.resolve_value(value) + else: + value = param_value_if_widget(value) if is_param_method(value, has_deps=True): value = value() diff --git a/holoviews/streams.py b/holoviews/streams.py index efdaddabef..41ee8924d9 100644 --- a/holoviews/streams.py +++ b/holoviews/streams.py @@ -50,8 +50,11 @@ def streams_list_from_dict(streams): params = {} for k, v in streams.items(): if 'panel' in sys.modules: - from panel.depends import param_value_if_widget - v = param_value_if_widget(v) + if util.param_version > util.Version('2.0.0rc1'): + v = param.parameterized.transform_reference(v) + else: + from panel.depends import param_value_if_widget + v = param_value_if_widget(v) if isinstance(v, param.Parameter) and v.owner is not None: params[k] = v else: @@ -222,8 +225,15 @@ def _process_streams(cls, streams): rename = {(p.owner, p.name): k for k, p in deps.get('kw', {}).items()} s = Params(parameters=dep_params, rename=rename) else: - invalid.append(s) - continue + if util.param_version > util.Version('2.0.0rc1'): + deps = param.parameterized.resolve_ref(s) + else: + deps = None + if deps: + s = Params(parameters=deps) + else: + invalid.append(s) + continue if isinstance(s, Params): pid = id(s.parameterized) overlap = (set(s.parameters) & parameterizeds[pid]) @@ -672,7 +682,7 @@ class Params(Stream): parameterized = param.ClassSelector(class_=(param.Parameterized, param.parameterized.ParameterizedMetaclass), constant=True, allow_None=True, doc=""" - Parameterized instance to watch for parameter changes.""") + Parameterized instance to watch for parameter changes.""", **util.disallow_refs) parameters = param.List(default=[], constant=True, doc=""" Parameters on the parameterized to watch.""") diff --git a/holoviews/tests/util/test_transform.py b/holoviews/tests/util/test_transform.py index 00384bdbda..3fad8b2cc5 100644 --- a/holoviews/tests/util/test_transform.py +++ b/holoviews/tests/util/test_transform.py @@ -481,7 +481,7 @@ def test_pandas_chained_methods(self): with warnings.catch_warnings(): # The kwargs is {'axis': None} and is already handled by the code. # This context manager can be removed, when it raises an TypeError instead of warning. - warnings.simplefilter("ignore", "Passing additional kwargs to Rolling.mean") + warnings.filterwarnings("ignore", "Passing additional kwargs to Rolling.mean") self.assert_apply(expr, self.linear_ints.rolling(1).mean()) diff --git a/holoviews/util/__init__.py b/holoviews/util/__init__.py index a22434a902..e63bf3f482 100644 --- a/holoviews/util/__init__.py +++ b/holoviews/util/__init__.py @@ -885,7 +885,7 @@ class Dynamic(param.ParameterizedFunction): Whether the cloned DynamicMap will share the same cache.""") streams = param.ClassSelector(default=[], class_=(list, dict), doc=""" - List of streams to attach to the returned DynamicMap""") + List of streams to attach to the returned DynamicMap""", **util.disallow_refs) def __call__(self, map_obj, **params): watch = params.pop('watch', True)