Skip to content

Commit

Permalink
Fix bug in is_viewable_param (#7454)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcSkovMadsen authored Nov 1, 2024
1 parent b43a52a commit c06f779
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 19 deletions.
49 changes: 48 additions & 1 deletion panel/tests/test_viewable.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
from panel.interact import interactive
from panel.pane import Markdown, Str, panel
from panel.param import ParamMethod
from panel.viewable import Viewable, Viewer
from panel.viewable import (
Child, Children, Viewable, Viewer, is_viewable_param,
)

from .util import jb_available

Expand Down Expand Up @@ -117,3 +119,48 @@ def test_clone_with_non_defaults():

assert ([(k, v) for k, v in sorted(v.param.values().items()) if k not in ('name')] ==
[(k, v) for k, v in sorted(clone.param.values().items()) if k not in ('name')])

def test_is_viewable_parameter():
class Example(param.Parameterized):
p_dict = param.Dict()
p_child = Child()
p_children = Children()

# ClassSelector
c_viewable = param.ClassSelector(class_=Viewable)
c_viewables = param.ClassSelector(class_=(Viewable,))
c_none = param.ClassSelector(class_=None)
c_tuple = param.ClassSelector(class_=tuple)
c_list_tuple = param.ClassSelector(class_=(list, tuple))

# List
l_no_item_type = param.List()
l_item_type_viewable = param.List(item_type=Viewable)
l_item_type_not_viewable = param.List(item_type=tuple)

l_item_types_viewable = param.List(item_type=(Viewable,))
l_item_types_not_viewable = param.List(item_type=(tuple,))
l_item_types_not_viewable2 = param.List(item_type=(list, tuple,))

example = Example()

assert not is_viewable_param(example.param.p_dict)
assert is_viewable_param(example.param.p_child)
assert is_viewable_param(example.param.p_children)

# ClassSelector
assert is_viewable_param(example.param.c_viewable)
assert is_viewable_param(example.param.c_viewables)
assert not is_viewable_param(example.param.c_none)
assert not is_viewable_param(example.param.c_tuple)
assert not is_viewable_param(example.param.c_list_tuple)

# List
assert not is_viewable_param(example.param.l_no_item_type)
assert not is_viewable_param(example.param.l_no_item_type)
assert is_viewable_param(example.param.l_item_type_viewable)
assert not is_viewable_param(example.param.l_item_type_not_viewable)

assert is_viewable_param(example.param.l_item_types_viewable)
assert not is_viewable_param(example.param.l_item_types_not_viewable)
assert not is_viewable_param(example.param.l_item_types_not_viewable2)
44 changes: 26 additions & 18 deletions panel/viewable.py
Original file line number Diff line number Diff line change
Expand Up @@ -1193,34 +1193,42 @@ def __set__(self, obj, val):



def _is_viewable_class_selector(class_selector: param.ClassSelector) -> bool:
if not class_selector.class_:
return False
if isinstance(class_selector.class_, tuple):
return all(issubclass(cls, Viewable) for cls in class_selector.class_)
return issubclass(class_selector.class_, Viewable)

def _is_viewable_list(param_list: param.List) -> bool:
if not param_list.item_type:
return False
if isinstance(param_list.item_type, tuple):
return all(issubclass(cls, Viewable) for cls in param_list.item_type)
return issubclass(param_list.item_type, Viewable)


def is_viewable_param(parameter: param.Parameter) -> bool:
"""
Detects whether the Parameter uniquely identifies a Viewable
type.
Determines if a parameter uniquely identifies a Viewable type.
Arguments
---------
parameter: param.Parameter
parameter : param.Parameter
The parameter to evaluate.
Returns
-------
Whether the Parameter specieis a Parameter type
bool
True if the parameter specifies a Viewable type, False otherwise.
"""
p = parameter
if (
isinstance(p, (Child, Children)) or
(isinstance(p, param.ClassSelector) and p.class_ and (
(isinstance(p.class_, tuple) and
all(issubclass(cls, Viewable) for cls in p.class_)) or
issubclass(p.class_, Viewable)
)) or
(isinstance(p, param.List) and p.item_type and (
(isinstance(p.item_type, tuple) and
all(issubclass(cls, Viewable) for cls in p.item_type)) or
issubclass(p.item_type, Viewable)
))
):
if isinstance(parameter, (Child, Children)):
return True
if isinstance(parameter, param.ClassSelector) and _is_viewable_class_selector(parameter):
return True
if isinstance(parameter, param.List) and _is_viewable_list(parameter):
return True

return False


Expand Down

0 comments on commit c06f779

Please sign in to comment.