Skip to content

Commit

Permalink
Merge 44978bd into 1af2264
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Apr 10, 2019
2 parents 1af2264 + 44978bd commit f8830d8
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 18 deletions.
41 changes: 26 additions & 15 deletions holoviews/streams.py
Expand Up @@ -166,30 +166,41 @@ def trigger(cls, streams):
def _on_trigger(self):
"""Called when a stream has been triggered"""


@classmethod
def _process_streams(cls, streams):
"""
Processes a list of streams promoting Parameterized objects and
methods to Param based streams.
"""
param_watch_support = util.param_version >= '1.8.0'
parameterizeds = [s.parameterized for s in streams if isinstance(s, Params)]
parameterizeds = defaultdict(list)
valid, invalid = [], []
for s in streams:
if not isinstance(s, Stream):
if isinstance(s, param.Parameterized) and param_watch_support:
if s not in parameterizeds:
s = Params(s)
else:
continue
elif util.is_param_method(s) and param_watch_support:
if not hasattr(s, "_dinfo") or util.get_method_owner(s) in parameterizeds:
continue
else:
s = ParamMethod(s)
else:
invalid.append(s)
if isinstance(s, Stream):
pass
elif isinstance(s, param.Parameter):
s = Params(s.owner, [s.name])
elif isinstance(s, param.Parameterized):
s = Params(s)
elif util.is_param_method(s):
if not hasattr(s, "_dinfo"):
continue
s = ParamMethod(s)
else:
invalid.append(s)
continue
if isinstance(s, Params):
pid = id(s.parameterized)
if pid in parameterizeds:
overlap = (set(s.parameters) & set(parameterizeds[pid]))
if overlap:
pname = type(s.parameterized).__name__
raise ValueError('Found multiple Params streams '
'subscribing to the %s parameter(s) '
'on the %s object. Ensure that '
'you only subscribe to a parameter '
'once.' % (list(overlap), pname))
parameterizeds[pid] += s.parameters
valid.append(s)
return valid, invalid

Expand Down
38 changes: 35 additions & 3 deletions holoviews/tests/teststreams.py
Expand Up @@ -181,9 +181,6 @@ def test_class_value_update(self):
class TestParamsStream(ComparisonTestCase):

def setUp(self):
if LooseVersion(param.__version__) < '1.8.0':
raise SkipTest('Params stream requires param >= 1.8.0')

class Inner(param.Parameterized):

x = param.Number(default = 0)
Expand Down Expand Up @@ -223,6 +220,41 @@ def subscriber(**kwargs):
inner.y = 2
self.assertEqual(values, [{'x': 2, 'y': 2}])

def test_param_stream_instance_separate_parameters(self):
inner = self.inner()

xparam = Params(inner, ['x'])
yparam = Params(inner, ['y'])

valid, invalid = Stream._process_streams([xparam, yparam])
self.assertEqual(len(valid), 2)
self.assertEqual(len(invalid), 0)

def test_param_stream_instance_overlapping_parameters(self):
inner = self.inner()

params1 = Params(inner)
params2 = Params(inner)

with self.assertRaises(ValueError):
Stream._process_streams([params1, params2])

def test_param_parameter_instance_separate_parameters(self):
inner = self.inner()

valid, invalid = Stream._process_streams([inner.param.x, inner.param.y])
xparam, yparam = valid

self.assertIs(xparam.parameterized, inner)
self.assertEqual(xparam.parameters, ['x'])
self.assertIs(yparam.parameterized, inner)
self.assertEqual(yparam.parameters, ['y'])

def test_param_parameter_instance_overlapping_parameters(self):
inner = self.inner()
with self.assertRaises(ValueError):
Stream._process_streams([inner.param.x, inner.param.x])

def test_param_stream_parameter_override(self):
inner = self.inner(x=2)
stream = Params(inner, parameters=['x'])
Expand Down

0 comments on commit f8830d8

Please sign in to comment.