import os
import param
from bokeh.models import (
Div, Slider, Select, RangeSlider as BkRangeSlider, MultiSelect,
Row as BkRow, CheckboxGroup, Toggle, Button, TextInput as
BkTextInput,Tabs as BkTabs, Column as BkColumn, TextInput,
AutocompleteInput as BkAutocompleteInput,
)
from panel.pane import Pane, PaneBase, Matplotlib, Bokeh, HTML
from panel.layout import Tabs, Row
from panel.param import Param, ParamMethod, ParamFunction, JSONInit
from panel.widgets import (
AutocompleteInput, DatePicker, DatetimeInput, LiteralInput,
NumberInput, RangeSlider
)
from panel.tests.util import mpl_available, mpl_figure
def test_instantiate_from_class():
class Test(param.Parameterized):
a = param.Number()
assert isinstance(Pane(Test), Param)
def test_instantiate_from_parameter():
class Test(param.Parameterized):
a = param.Number()
assert isinstance(Pane(Test.param.a), Param)
def test_instantiate_from_parameters():
class Test(param.Parameterized):
a = param.Number()
assert isinstance(Pane(Test.param), Param)
def test_instantiate_from_instance():
class Test(param.Parameterized):
a = param.Number()
assert isinstance(Pane(Test()), Param)
def test_instantiate_from_parameter_on_instance():
class Test(param.Parameterized):
a = param.Number()
assert isinstance(Pane(Test().param.a), Param)
def test_instantiate_from_parameters_on_instance():
class Test(param.Parameterized):
a = param.Number()
assert isinstance(Pane(Test().param), Param)
def test_param_pane_repr(document, comm):
class Test(param.Parameterized):
pass
assert repr(Pane(Test())) == 'Param(Test)'
def test_param_pane_repr_with_params(document, comm):
class Test(param.Parameterized):
a = param.Number()
b = param.Number()
assert repr(Pane(Test(), parameters=['a'])) == "Param(Test, parameters=['a'])"
# With a defined name.
test_pane = Pane(Test(), parameters=['a'], name='Another')
assert repr(test_pane) == "Param(Test, name='Another', parameters=['a'])"
def test_get_root(document, comm):
class Test(param.Parameterized):
pass
test = Test()
test_pane = Pane(test)
model = test_pane.get_root(document, comm=comm)
assert isinstance(model, BkColumn)
assert len(model.children) == 1
div = model.children[0]
assert isinstance(div, Div)
assert div.text == ''+test.name[:-5]+''
def test_single_param(document, comm):
class Test(param.Parameterized):
a = param.Parameter(default=0)
test = Test()
test_pane = Pane(test.param.a)
model = test_pane.get_root(document, comm=comm)
assert isinstance(model, BkColumn)
assert len(model.children) == 1
widget = model.children[0]
assert isinstance(widget, TextInput)
assert widget.value == '0'
def test_get_root_tabs(document, comm):
class Test(param.Parameterized):
pass
test = Test()
test_pane = Pane(test, expand_layout=Tabs)
model = test_pane.get_root(document, comm=comm)
assert isinstance(model, BkTabs)
assert len(model.tabs) == 1
box = model.tabs[0].child
assert isinstance(box, BkColumn)
assert len(box.children) == 0
def test_number_param(document, comm):
class Test(param.Parameterized):
a = param.Number(default=1.2, bounds=(0, 5))
test = Test()
test_pane = Pane(test)
model = test_pane.get_root(document, comm=comm)
slider = model.children[1]
assert isinstance(slider, Slider)
assert slider.value == 1.2
assert slider.start == 0
assert slider.end == 5
assert slider.step == 0.1
assert slider.disabled == False
# Check changing param value updates widget
test.a = 3.3
assert slider.value == 3.3
# Check changing param attribute updates widget
a_param = test.param['a']
a_param.bounds = (0.1, 5.5)
assert slider.start == 0.1
assert slider.end == 5.5
a_param.constant = True
assert slider.disabled == True
# Ensure cleanup works
test_pane._cleanup(model)
a_param.constant = False
a_param.bounds = (-0.1, 3.8)
test.a = 0.5
assert slider.value == 3.3
assert slider.start == 0.1
assert slider.end == 5.5
assert slider.disabled == True
def test_boolean_param(document, comm):
class Test(param.Parameterized):
a = param.Boolean(default=False)
test = Test()
test_pane = Pane(test)
model = test_pane.get_root(document, comm=comm)
checkbox = model.children[1]
assert isinstance(checkbox, CheckboxGroup)
assert checkbox.labels == ['A']
assert checkbox.active == []
assert checkbox.disabled == False
# Check changing param value updates widget
test.a = True
assert checkbox.active == [0]
# Check changing param attribute updates widget
a_param = test.param['a']
a_param.constant = True
assert checkbox.disabled == True
# Ensure cleanup works
test_pane._cleanup(model)
a_param.constant = False
test.a = False
assert checkbox.active == [0]
assert checkbox.disabled == True
def test_range_param(document, comm):
class Test(param.Parameterized):
a = param.Range(default=(0.1, 0.5), bounds=(0, 1.1))
test = Test()
test_pane = Pane(test)
model = test_pane.get_root(document, comm=comm)
widget = model.children[1]
assert isinstance(widget, BkRangeSlider)
assert widget.start == 0
assert widget.end == 1.1
assert widget.value == (0.1, 0.5)
# Check changing param value updates widget
test.a = (0.2, 0.4)
assert widget.value == (0.2, 0.4)
# Check changing param attribute updates widget
a_param = test.param['a']
a_param.bounds = (0.1, 0.6)
assert widget.start == 0.1
assert widget.end == 0.6
a_param.constant = True
assert widget.disabled == True
# Ensure cleanup works
test_pane._cleanup(model)
a_param.constant = False
a_param.bounds = (-1, 1)
test.a = (0.05, 0.2)
assert widget.value == (0.2, 0.4)
assert widget.start == 0.1
assert widget.end == 0.6
assert widget.disabled == True
def test_integer_param(document, comm):
class Test(param.Parameterized):
a = param.Integer(default=2, bounds=(0, 5))
test = Test()
test_pane = Pane(test)
model = test_pane.get_root(document, comm=comm)
slider = model.children[1]
assert isinstance(slider, Slider)
assert slider.value == 2
assert slider.start == 0
assert slider.end == 5
assert slider.step == 1
assert slider.disabled == False
# Check changing param value updates widget
test.a = 3
assert slider.value == 3
# Check changing param attribute updates widget
a_param = test.param['a']
a_param.bounds = (1, 6)
assert slider.start == 1
assert slider.end == 6
a_param.constant = True
assert slider.disabled == True
# Ensure cleanup works
test_pane._cleanup(model)
a_param.constant = False
a_param.bounds = (-1, 7)
test.a = 1
assert slider.value == 3
assert slider.start == 1
assert slider.end == 6
assert slider.disabled == True
def test_object_selector_param(document, comm):
class Test(param.Parameterized):
a = param.ObjectSelector(default='b', objects=[1, 'b', 'c'])
test = Test()
test_pane = Pane(test)
model = test_pane.get_root(document, comm=comm)
select = model.children[1]
assert isinstance(select, Select)
assert select.options == [('1','1'), ('b','b'), ('c','c')]
assert select.value == 'b'
assert select.disabled == False
# Check changing param value updates widget
test.a = 1
assert select.value == '1'
# Check changing param attribute updates widget
a_param = test.param['a']
a_param.objects = ['c', 'd', 1]
assert select.options == [('c','c'), ('d','d'), ('1','1')]
a_param.constant = True
assert select.disabled == True
# Ensure cleanup works
test_pane._cleanup(model)
a_param.constant = False
a_param.objects = [1, 'c', 'd']
test.a = 'd'
assert select.value == '1'
assert select.options == [('c','c'), ('d','d'), ('1','1')]
assert select.disabled == True
def test_list_selector_param(document, comm):
class Test(param.Parameterized):
a = param.ListSelector(default=['b', 1], objects=[1, 'b', 'c'])
test = Test()
test_pane = Pane(test)
model = test_pane.get_root(document, comm=comm)
slider = model.children[1]
assert isinstance(slider, MultiSelect)
assert slider.options == ['1', 'b', 'c']
assert slider.value == ['b', '1']
assert slider.disabled == False
# Check changing param value updates widget
test.a = ['c', 1]
assert slider.value == ['c', '1']
# Check changing param attribute updates widget
a_param = test.param['a']
a_param.objects = ['c', 'd', 1]
assert slider.options == ['c', 'd', '1']
a_param.constant = True
assert slider.disabled == True
# Ensure cleanup works
test_pane._cleanup(model)
a_param.constant = False
a_param.objects = [1, 'c', 'd']
test.a = ['d']
assert slider.value == ['c', '1']
assert slider.options == ['c', 'd', '1']
assert slider.disabled == True
def test_action_param(document, comm):
class Test(param.Parameterized):
a = param.Action(lambda x: setattr(x, 'b', 2))
b = param.Number(default=1)
test = Test()
test_pane = Pane(test)
model = test_pane.get_root(document, comm=comm)
button = model.children[1]
assert isinstance(button, Button)
# Check that the action is actually executed
pn_button = test_pane.layout[1]
pn_button.clicks = 1
assert test.b == 2
def test_explicit_params(document, comm):
class Test(param.Parameterized):
a = param.Boolean(default=False)
b = param.Integer(default=1)
test = Test()
test_pane = Pane(test, parameters=['a'])
model = test_pane.get_root(document, comm=comm)
assert len(model.children) == 2
assert isinstance(model.children[1], CheckboxGroup)
def test_param_precedence(document, comm):
class Test(param.Parameterized):
a = param.Number(default=1.2, bounds=(0, 5))
test = Test()
test_pane = Pane(test)
# Check changing precedence attribute hides and shows widget
a_param = test.param['a']
a_param.precedence = -1
assert test_pane._widgets['a'] not in test_pane._widget_box.objects
a_param.precedence = 1
assert test_pane._widgets['a'] in test_pane._widget_box.objects
a_param.precedence = None
assert test_pane._widgets['a'] in test_pane._widget_box.objects
def test_hide_constant(document, comm):
class Test(param.Parameterized):
a = param.Number(default=1.2, bounds=(0, 5), constant=True)
test = Test()
test_pane = Pane(test, parameters=['a'], hide_constant=True)
model = test_pane.get_root(document, comm=comm)
slider = model.children[1]
assert not slider.visible
test.param.a.constant = False
assert slider.visible
def test_param_label(document, comm):
class Test(param.Parameterized):
a = param.Number(default=1.2, bounds=(0, 5), label='A')
b = param.Action(label='B')
test = Test()
test_pane = Pane(test)
# Check updating label changes widget name
a_param = test.param['a']
a_param.label = 'B'
assert test_pane._widgets['a'].name == 'B'
b_param = test.param['b']
b_param.label = 'C'
assert test_pane._widgets['b'].name == 'C'
def test_param_precedence_ordering(document, comm):
class Test(param.Parameterized):
a = param.Number(default=1.2, bounds=(0, 5), precedence=-1)
b = param.Boolean(default=True, precedence=1)
test = Test()
test_pane = Pane(test)
# Check changing precedence attribute hides and shows widget
a_param = test.param['a']
a_param.precedence = 2
assert test_pane._widget_box.objects == [test_pane._widgets[w] for w in ('_title', 'b', 'a')]
a_param.precedence = 1
assert test_pane._widget_box.objects == [test_pane._widgets[w] for w in ('_title', 'a', 'b')]
def test_param_step(document, comm):
class Test(param.Parameterized):
a = param.Number(default=1.2, bounds=(0, 5), step=0.1)
test = Test()
test_pane = Pane(test)
assert test_pane._widgets['a'].step == 0.1
a_param = test.param['a']
a_param.step = 0.25
assert test_pane._widgets['a'].step == 0.25
def test_replace_param_object(document, comm):
class Test(param.Parameterized):
a = param.Number(bounds=(0, 10))
pane = Param()
model = pane.get_root(document, comm=comm)
assert model.children == []
pane.object = Test()
assert len(model.children) == 2
title, widget = model.children
assert isinstance(title, Div)
assert title.text == 'Test'
assert isinstance(widget, Slider)
assert widget.start == 0
assert widget.end == 10
# Check when object is from parameters
pane.object = Test().param
assert len(model.children) == 2
title, widget = model.children
assert isinstance(title, Div)
assert title.text == 'Test'
assert isinstance(widget, Slider)
assert widget.start == 0
assert widget.end == 10
# Check when object is None
pane.object = None
assert len(model.children) == 0
def test_set_name(document, comm):
class Test(param.Parameterized):
a = param.Number(bounds=(0, 10))
b = param.String(default='A')
pane = Param(Test(), name='First')
model = pane.get_root(document, comm=comm)
assert len(model.children) == 3
title, slider, text = model.children
assert isinstance(title, Div)
# Check setting name displays in as a title
assert title.text == 'First'
assert isinstance(slider, Slider)
assert isinstance(text, TextInput)
pane.name = 'Second'
assert len(model.children) == 3
title, _, _ = model.children
assert isinstance(title, Div)
# Check the title updates with name
assert title.text == 'Second'
def test_set_parameters(document, comm):
class Test(param.Parameterized):
a = param.Number(bounds=(0, 10))
b = param.String(default='A')
pane = Param(Test())
model = pane.get_root(document, comm=comm)
assert len(model.children) == 3
title, slider, text = model.children
assert isinstance(title, Div)
assert isinstance(slider, Slider)
assert isinstance(text, TextInput)
pane.parameters = ['b']
assert len(model.children) == 2
title, text = model.children
assert isinstance(title, Div)
assert isinstance(text, TextInput)
def test_trigger_parameters(document, comm):
class Test(param.Parameterized):
a = param.ListSelector(objects=[1,2,3,4], default=list())
t = Test()
t.a.append(4)
pane = Param(t.param.a)
t.a.append(1)
t.param.trigger('a')
assert pane[0].value == [4, 1]
def test_set_display_threshold(document, comm):
class Test(param.Parameterized):
a = param.Number(bounds=(0, 10), precedence=1)
b = param.String(default='A', precedence=2)
pane = Param(Test())
model = pane.get_root(document, comm=comm)
assert len(model.children) == 3
title, slider, text = model.children
assert isinstance(title, Div)
assert isinstance(slider, Slider)
assert isinstance(text, TextInput)
pane.display_threshold = 1.5
assert len(model.children) == 2
title, text = model.children
assert isinstance(title, Div)
assert isinstance(text, TextInput)
def test_set_widgets(document, comm):
class Test(param.Parameterized):
a = param.Number(default=1, bounds=(0, 10), precedence=1)
b = param.String(default='A', precedence=2)
pane = Param(Test())
model = pane.get_root(document, comm=comm)
assert len(model.children) == 3
title, slider, text = model.children
assert isinstance(title, Div)
assert isinstance(slider, Slider)
assert isinstance(text, TextInput)
pane.widgets = {'a': LiteralInput(value=1, type=(float, int))}
assert len(model.children) == 3
title, number, text = model.children
assert isinstance(title, Div)
assert isinstance(number, TextInput)
assert isinstance(text, TextInput)
pane.widgets = {'a': {'height':100}}
assert len(model.children) == 3
title, number, text = model.children
assert isinstance(title, Div)
assert isinstance(number, Slider)
assert number.height == 100
assert isinstance(text, TextInput)
pane.widgets = {'a': {'type': LiteralInput, 'height':100}}
assert len(model.children) == 3
title, number, text = model.children
assert isinstance(title, Div)
assert isinstance(number, TextInput)
assert number.height == 100
assert isinstance(text, TextInput)
def test_set_widgets_throttled(document, comm):
class Test(param.Parameterized):
a = param.Number(default=0, bounds=(0, 10), precedence=1)
test = Test()
pane = Param(test)
model = pane.get_root(document, comm=comm)
pane.widgets = {"a": {"throttled": False}}
assert len(model.children) == 2
_, number = model.children
number.value = 1
assert number.value == 1
assert number.value_throttled != 1
assert test.a == 1
test.a = 2
assert number.value == 2
assert number.value_throttled != 2
assert test.a == 2
# By setting throttled to true,
# `test.a` is linked to `number.value_throttled`
# instead of `number.value`.
pane.widgets = {"a": {"throttled": True}}
assert len(model.children) == 2
_, number = model.children
pane._widgets['a']._process_events({'value_throttled': 3})
assert number.value != 3
assert test.a == 3
pane._widgets['a']._process_events({'value': 4})
assert test.a == 3
assert number.value == 4
def test_set_show_name(document, comm):
class Test(param.Parameterized):
a = param.Number(bounds=(0, 10))
pane = Param(Test())
model = pane.get_root(document, comm=comm)
assert len(model.children) == 2
title, widget = model.children
assert isinstance(title, Div)
assert isinstance(widget, Slider)
pane.show_name = False
assert len(model.children) == 1
assert isinstance(model.children[0], Slider)
def test_set_show_labels(document, comm):
class Test(param.Parameterized):
a = param.Number(bounds=(0, 10))
pane = Param(Test())
model = pane.get_root(document, comm=comm)
assert len(model.children) == 2
title, widget = model.children
assert isinstance(title, Div)
assert isinstance(widget, Slider)
assert widget.title == 'A'
pane.show_labels = False
assert len(model.children) == 2
assert isinstance(model.children[1], Slider)
assert model.children[1].title == ''
def test_expand_param_subobject(document, comm):
class Test(param.Parameterized):
a = param.Parameter()
test = Test(a=Test(name='Nested'))
test_pane = Pane(test)
model = test_pane.get_root(document, comm=comm)
toggle = model.children[1].children[1]
assert isinstance(toggle, Toggle)
# Expand subpane
test_pane._widgets['a'][1].value = True
assert len(model.children) == 3
_, _, subpanel = test_pane.layout.objects
col = model.children[2]
assert isinstance(col, BkColumn)
assert isinstance(col, BkColumn)
assert len(col.children) == 2
div, widget = col.children
assert div.text == 'Nested'
assert isinstance(widget, BkTextInput)
# Collapse subpanel
test_pane._widgets['a'][1].value = False
assert len(model.children) == 2
def test_switch_param_subobject(document, comm):
class Test(param.Parameterized):
a = param.ObjectSelector()
o1 = Test(name='Subobject 1')
o2 = Test(name='Subobject 2')
Test.param['a'].objects = [o1, o2, 3]
test = Test(a=o1, name='Nested')
test_pane = Pane(test)
model = test_pane.get_root(document, comm=comm)
toggle = model.children[1].children[1]
assert isinstance(toggle, Toggle)
# Expand subpane
test_pane._widgets['a'][1].value = True
assert len(model.children) == 3
_, _, subpanel = test_pane.layout.objects
col = model.children[2]
assert isinstance(col, BkColumn)
assert len(col.children) == 2
div, row = col.children
assert div.text == 'Subobject 1'
assert isinstance(row.children[0], Select)
# Switch subobject
test_pane._widgets['a'][0].value = o2
_, _, subpanel = test_pane.layout.objects
col = model.children[2]
assert isinstance(col, BkColumn)
assert len(col.children) == 2
div, row = col.children
assert div.text == 'Subobject 2'
assert isinstance(row.children[0], Select)
# Collapse subpanel
test_pane._widgets['a'][1].value = False
assert len(model.children) == 2
assert subpanel._models == {}
def test_expand_param_subobject_into_row(document, comm):
class Test(param.Parameterized):
a = param.Parameter()
test = Test(a=Test(name='Nested'))
row = Row()
test_pane = Pane(test, expand_layout=row)
layout = Row(test_pane, row)
model = layout.get_root(document, comm=comm)
toggle = model.children[0].children[1].children[1]
assert isinstance(toggle, Toggle)
# Expand subpane
test_pane._widgets['a'][1].value = True
assert len(model.children) == 2
subpanel = row.objects[0]
row = model.children[1]
assert isinstance(row, BkRow)
assert len(row.children) == 1
box = row.children[0]
assert isinstance(box, BkColumn)
assert len(box.children) == 2
div, widget = box.children
assert div.text == 'Nested'
assert isinstance(widget, BkTextInput)
# Collapse subpanel
test_pane._widgets['a'][1].value = False
assert len(row.children) == 0
assert subpanel._models == {}
def test_expand_param_subobject_expand(document, comm):
class Test(param.Parameterized):
a = param.Parameter()
test = Test(a=Test(name='Nested'))
test_pane = Pane(test, expand=True, expand_button=True)
model = test_pane.get_root(document, comm=comm)
toggle = model.children[1].children[1]
assert isinstance(toggle, Toggle)
# Expand subpane
assert len(model.children) == 3
_, _, subpanel = test_pane.layout.objects
col = model.children[2]
assert isinstance(col, BkColumn)
assert len(col.children) == 2
div, widget = col.children
assert div.text == 'Nested'
assert isinstance(widget, BkTextInput)
# Collapse subpanel
test_pane._widgets['a'][1].value = False
assert len(model.children) == 2
assert subpanel._models == {}
def test_param_subobject_expand_no_toggle(document, comm):
class Test(param.Parameterized):
a = param.Parameter()
test = Test(a=Test(name='Nested'))
test_pane = Pane(test, expand=True,
expand_button=False)
model = test_pane.get_root(document, comm=comm)
# Assert no toggle was added
assert len(model.children) == 3
# Expand subpane
_, _, subpanel = test_pane.layout.objects
div, widget = model.children[2].children
assert div.text == 'Nested'
assert isinstance(widget, BkTextInput)
def test_expand_param_subobject_tabs(document, comm):
class Test(param.Parameterized):
abc = param.Parameter()
test = Test(abc=Test(name='Nested'), name='A')
test_pane = Pane(test, expand_layout=Tabs)
model = test_pane.get_root(document, comm=comm)
toggle = model.tabs[0].child.children[0].children[1]
assert isinstance(toggle, Toggle)
# Expand subpanel
test_pane._widgets['abc'][1].value = True
assert len(model.tabs) == 2
_, subpanel = test_pane.layout.objects
subtabs = model.tabs[1].child
assert model.tabs[1].title == 'Abc'
assert isinstance(subtabs, BkTabs)
assert len(subtabs.tabs) == 1
assert subtabs.tabs[0].title == 'Nested'
box = subtabs.tabs[0].child
assert isinstance(box, BkColumn)
assert len(box.children) == 1
widget = box.children[0]
assert isinstance(widget, BkTextInput)
# Collapse subpanel
test_pane._widgets['abc'][1].value = False
assert len(model.tabs) == 1
def test_param_js_callbacks(document, comm):
class JsButton(param.Parameterized):
param_btn = param.Action(lambda self: print('Action Python Response'), label='Action')
param_button = Param(JsButton())
code = "console.log('Action button clicked')"
param_button[1].js_on_click(code=code)
model = param_button.get_root(document, comm=comm)
button = model.children[1]
assert len(button.js_event_callbacks) == 1
callbacks = button.js_event_callbacks
assert 'button_click' in callbacks
assert len(callbacks['button_click']) == 1
assert code in callbacks['button_click'][0].code
def test_param_calendar_date_mapping():
class Test(param.Parameterized):
a = param.CalendarDate()
assert isinstance(Param(Test().param).layout[1], DatePicker)
def test_param_date_mapping():
class Test(param.Parameterized):
a = param.Date()
assert isinstance(Param(Test().param).layout[1], DatetimeInput)
class View(param.Parameterized):
a = param.Integer(default=0)
b = param.Parameter()
@param.depends('a')
def view(self):
return Div(text='%d' % self.a)
@param.depends('b.param')
def subobject_view(self):
return Div(text='%d' % self.b.a)
@param.depends('a')
def mpl_view(self):
return mpl_figure()
@param.depends('a')
def mixed_view(self):
return self.view() if (self.a % 2) else self.mpl_view()
def test_get_param_function_pane_type():
test = View()
def view(a):
return Div(text='%d' % a)
assert PaneBase.get_pane_type(view) is not ParamFunction
assert PaneBase.get_pane_type(param.depends(test.param.a)(view)) is ParamFunction
def test_param_function_pane(document, comm):
test = View()
@param.depends(test.param.a)
def view(a):
return Div(text='%d' % a)
pane = Pane(view)
inner_pane = pane._pane
assert isinstance(inner_pane, Bokeh)
# Create pane
row = pane.get_root(document, comm=comm)
assert isinstance(row, BkRow)
assert len(row.children) == 1
model = row.children[0]
assert pane._models[row.ref['id']][0] is row
assert isinstance(model, Div)
assert model.text == '0'
# Update pane
test.a = 5
new_model = row.children[0]
assert inner_pane is pane._pane
assert new_model.text == '5'
assert pane._models[row.ref['id']][0] is row
# Cleanup pane
pane._cleanup(row)
assert pane._models == {}
assert inner_pane._models == {}
def test_param_function_pane_update(document, comm):
test = View()
objs = {
0: HTML("012"),
1: HTML("123")
}
@param.depends(test.param.a)
def view(a):
return objs[a]
pane = Pane(view)
inner_pane = pane._pane
assert inner_pane is not objs[0]
assert inner_pane.object is objs[0].object
assert pane._internal
test.a = 1
assert pane._pane is inner_pane
assert pane._internal
objs[0].param.watch(print, ['object'])
test.a = 0
assert pane._pane is not inner_pane
assert not pane._internal
def test_get_param_method_pane_type():
assert PaneBase.get_pane_type(View().view) is ParamMethod
def test_param_method_pane(document, comm):
test = View()
pane = Pane(test.view)
inner_pane = pane._pane
assert isinstance(inner_pane, Bokeh)
# Create pane
row = pane.get_root(document, comm=comm)
assert isinstance(row, BkRow)
assert len(row.children) == 1
model = row.children[0]
assert pane._models[row.ref['id']][0] is row
assert isinstance(model, Div)
assert model.text == '0'
# Update pane
test.a = 5
new_model = row.children[0]
assert inner_pane is pane._pane
assert new_model.text == '5'
assert pane._models[row.ref['id']][0] is row
# Cleanup pane
pane._cleanup(row)
assert pane._models == {}
assert inner_pane._models == {}
def test_param_method_pane_subobject(document, comm):
subobject = View(name='Nested', a=42)
test = View(b=subobject)
pane = Pane(test.subobject_view)
inner_pane = pane._pane
assert isinstance(inner_pane, Bokeh)
# Create pane
row = pane.get_root(document, comm=comm)
assert isinstance(row, BkRow)
assert len(row.children) == 1
model = row.children[0]
assert isinstance(model, Div)
assert model.text == '42'
# Ensure that subobject is being watched
watchers = pane._callbacks
assert any(w.inst is subobject for w in watchers)
assert pane._models[row.ref['id']][0] is row
# Ensure that switching the subobject triggers update in watchers
new_subobject = View(name='Nested', a=42)
test.b = new_subobject
assert pane._models[row.ref['id']][0] is row
watchers = pane._callbacks
assert not any(w.inst is subobject for w in watchers)
assert any(w.inst is new_subobject for w in watchers)
# Cleanup pane
pane._cleanup(row)
assert pane._models == {}
assert inner_pane._models == {}
@mpl_available
def test_param_method_pane_mpl(document, comm):
test = View()
pane = Pane(test.mpl_view)
inner_pane = pane._pane
assert isinstance(inner_pane, Matplotlib)
# Create pane
row = pane.get_root(document, comm=comm)
assert isinstance(row, BkRow)
assert len(row.children) == 1
model = row.children[0]
assert pane._models[row.ref['id']][0] is row
text = model.text
# Update pane
test.a = 5
new_model = row.children[0]
assert inner_pane is pane._pane
assert new_model is model
assert new_model.text != text
assert pane._models[row.ref['id']][0] is row
# Cleanup pane
pane._cleanup(row)
assert pane._models == {}
assert inner_pane._models == {}
@mpl_available
def test_param_method_pane_changing_type(document, comm):
test = View()
pane = Pane(test.mixed_view)
inner_pane = pane._pane
assert isinstance(inner_pane, Matplotlib)
# Create pane
row = pane.get_root(document, comm=comm)
assert isinstance(row, BkRow)
assert len(row.children) == 1
model = row.children[0]
text = model.text
assert text.startswith('<img src=')
# Update pane
test.a = 5
new_model = row.children[0]
new_pane = pane._pane
assert isinstance(new_pane, Bokeh)
assert isinstance(new_model, Div)
assert new_model.text != text
# Cleanup pane
new_pane._cleanup(row)
assert new_pane._models == {}
def test_jsoninit_class_from_env_var():
os.environ['PARAM_JSON_INIT'] = '{"a": 1}'
json_init = JSONInit()
class Test(param.Parameterized):
a = param.Integer()
json_init(Test)
assert Test.a == 1
del os.environ['PARAM_JSON_INIT']
def test_jsoninit_instance_from_env_var():
os.environ['PARAM_JSON_INIT'] = '{"a": 2}'
json_init = JSONInit()
class Test(param.Parameterized):
a = param.Integer()
test = Test()
json_init(test)
assert test.a == 2
del os.environ['PARAM_JSON_INIT']
def test_change_object_and_keep_parameters():
"""Test that https://github.com/holoviz/panel/issues/1581 is solved"""
# Given
class TextModel(param.Parameterized):
text = param.String()
param2 = param.String()
class TextView(param.Parameterized):
text = param.ClassSelector(class_=TextModel)
text_pane = param.Parameter()
def __init__(self, **params):
params["text"] = TextModel(text="Original Text")
super().__init__(**params)
self.text_pane = Param(
self.text, parameters=["text"]
)
@param.depends("text", watch=True)
def _update_text_pane(self, *_):
self.text_pane.object = self.text
view = TextView()
assert view.text_pane.parameters==["text"]
# When
view.text = TextModel(text="New TextModel")
# Then
assert view.text_pane.parameters==["text"]
def test_rerender_bounded_widget_when_bounds_set_and_unset():
class Test(param.Parameterized):
num = param.Range()
test = Test()
p = Param(test)
assert isinstance(p._widgets['num'], LiteralInput)
assert p._widgets['num'] in p._widget_box
test.param.num.bounds = (0, 5)
assert isinstance(p._widgets['num'], RangeSlider)
assert p._widgets['num'] in p._widget_box
test.param.num.bounds = (None, 5)
assert isinstance(p._widgets['num'], LiteralInput)
assert p._widgets['num'] in p._widget_box
def test_numberinput_bounds():
class Test(param.Parameterized):
num = param.Number(default=5, bounds=(0, 5))
test = Test()
p = Param(test, widgets={'num': NumberInput})
numinput = p.layout[1]
assert numinput.start == 0
assert numinput.end == 5
def test_set_widget_autocompleteinput(document, comm):
class Test(param.Parameterized):
# Testing with default='' and check_on_set=False since this feels
# like the most sensible default config for Selector -> AutocompleteInput
choice = param.Selector(default='', objects=['a', 'b'], check_on_set=False)
test = Test()
test_pane = Param(test, widgets={'choice': AutocompleteInput})
model = test_pane.get_root(document, comm=comm)
autocompleteinput = model.children[1]
assert isinstance(autocompleteinput, BkAutocompleteInput)
assert autocompleteinput.completions == ['a', 'b']
assert autocompleteinput.value == ''
assert autocompleteinput.disabled == False
# Check changing param value updates widget
test.choice = 'b'
assert autocompleteinput.value == 'b'
# Check changing param attribute updates widget
test.param['choice'].objects = ['c', 'd']
assert autocompleteinput.completions == ['c', 'd']
assert autocompleteinput.value == ''
def test_set_widget_autocompleteinput_empty_objects(document, comm):
class Test(param.Parameterized):
# Testing with default='' and check_on_set=False since this feels
# like the most sensible default config for Selector -> AutocompleteInput
choice = param.Selector(default='', objects=[], check_on_set=False)
test = Test()
test_pane = Param(test, widgets={'choice': AutocompleteInput})
model = test_pane.get_root(document, comm=comm)
autocompleteinput = model.children[1]
assert isinstance(autocompleteinput, BkAutocompleteInput)
assert autocompleteinput.completions == ['']
assert autocompleteinput.value == ''
assert autocompleteinput.disabled == False
def test_sorted():
class MyClass(param.Parameterized):
valueb = param.Integer(label="zzz")
valuez = param.String(label="aaa")
valuea = param.Integer(label="bbb")
my_class = MyClass()
_, input1, input2, input3 = Param(my_class, sort=True)
assert input1.name=="aaa"
assert input2.name=="bbb"
assert input3.name=="zzz"
def test_sorted_func():
class MyClass(param.Parameterized):
valueb = param.Integer(label="bac")
valuez = param.String(label="acb")
valuea = param.Integer(label="cba")
my_class = MyClass()
def sort_func(x):
return x[1].label[::-1]
_, input1, input2, input3 = Param(my_class, sort=sort_func)
assert input1.name=="cba"
assert input2.name=="acb"
assert input3.name=="bac"