diff --git a/holoviews/core/spaces.py b/holoviews/core/spaces.py index 9f8b9fe6ac..47477db66e 100644 --- a/holoviews/core/spaces.py +++ b/holoviews/core/spaces.py @@ -542,7 +542,7 @@ 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 not args and not kwargs: return self.callable() + 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 = [] for stream in [s for i in inputs for s in get_nested_streams(i)]: diff --git a/holoviews/tests/teststreams.py b/holoviews/tests/teststreams.py index 1755c66dc4..15a4548329 100644 --- a/holoviews/tests/teststreams.py +++ b/holoviews/tests/teststreams.py @@ -276,10 +276,12 @@ class Inner(param.Parameterized): action = param.Action(lambda o: o.param.trigger('action')) x = param.Number(default = 0) y = param.Number(default = 0) + count = param.Integer(default=0) @param.depends('x') def method(self): - pass + self.count += 1 + return Points([]) @param.depends('action') def action_method(self): @@ -312,7 +314,7 @@ def subscriber(**kwargs): def test_param_method_depends_no_deps(self): inner = self.inner() stream = ParamMethod(inner.method_no_deps) - self.assertEqual(set(stream.parameters), {'x', 'y', 'action', 'name'}) + self.assertEqual(set(stream.parameters), {'x', 'y', 'action', 'name', 'count'}) self.assertEqual(stream.contents, {}) values = [] @@ -341,6 +343,32 @@ def subscriber(**kwargs): inner.y = 2 self.assertEqual(values, [{}]) + def test_param_method_depends_trigger_no_memoization(self): + inner = self.inner() + stream = ParamMethod(inner.method) + self.assertEqual(set(stream.parameters), {'x'}) + self.assertEqual(stream.contents, {}) + + values = [] + def subscriber(**kwargs): + values.append(kwargs) + + stream.add_subscriber(subscriber) + inner.x = 2 + inner.param.trigger('x') + self.assertEqual(values, [{}, {}]) + + def test_dynamicmap_param_method_deps_memoization(self): + inner = self.inner() + dmap = DynamicMap(inner.method) + stream = dmap.streams[0] + self.assertEqual(set(stream.parameters), {'x'}) + self.assertEqual(stream.contents, {}) + + dmap[()] + dmap[()] + self.assertEqual(inner.count, 1) + def test_dynamicmap_param_method_no_deps(self): inner = self.inner() dmap = DynamicMap(inner.method_no_deps)