Skip to content

Commit

Permalink
Listselectordefault (#817)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbednar authored Aug 17, 2023
1 parent 37b82cf commit 83e57ea
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 29 deletions.
10 changes: 5 additions & 5 deletions numbergen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ class TimeAwareRandomState(TimeAware):
random_generator = param.Parameter(
default=random.Random(c_size_t(hash((500,500))).value), doc=
"""
Random state used by the object. This may may be an instance
Random state used by the object. This may be an instance
of random.Random from the Python standard library or an
instance of numpy.random.RandomState.
Expand Down Expand Up @@ -458,9 +458,9 @@ class UniformRandom(RandomDistribution):
See the random module for further details.
"""

lbound = param.Number(default=0.0,doc="inclusive lower bound")
lbound = param.Number(default=0.0,doc="Inclusive lower bound.")

ubound = param.Number(default=1.0,doc="exclusive upper bound")
ubound = param.Number(default=1.0,doc="Exclusive upper bound.")


def __call__(self):
Expand Down Expand Up @@ -500,8 +500,8 @@ class UniformRandomInt(RandomDistribution):
See the randint function in the random module for further details.
"""

lbound = param.Number(default=0,doc="inclusive lower bound")
ubound = param.Number(default=1000,doc="inclusive upper bound")
lbound = param.Number(default=0,doc="Inclusive lower bound.")
ubound = param.Number(default=1000,doc="Inclusive upper bound.")


def __call__(self):
Expand Down
47 changes: 30 additions & 17 deletions param/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1666,7 +1666,7 @@ def sig(self):


class _SignatureSelector(Parameter):

# Needs docstring; why is this a separate mixin?
_slot_defaults = _dict_update(
SelectorBase._slot_defaults, _objects=_compute_selector_default,
compute_default_fn=None, check_on_set=_compute_selector_checking_default,
Expand Down Expand Up @@ -1748,17 +1748,13 @@ def __init__(self, *, objects=Undefined, default=Undefined, instantiate=Undefine
self.allow_None = self._slot_defaults['allow_None']
else:
self.allow_None = allow_None
if self.default is not None and self.check_on_set is True:
self._validate(self.default)
if self.default is not None:
self._validate_value(self.default)
self._update_state()

def _update_state(self):
if (
self.check_on_set is False
and self.default is not None
and self.default not in self.objects
):
self.objects.append(self.default)
if self.check_on_set is False and self.default is not None:
self._ensure_value_is_in_objects(self.default)

@property
def objects(self):
Expand Down Expand Up @@ -1786,18 +1782,17 @@ def compute_default(self):
"""
if self.default is None and callable(self.compute_default_fn):
self.default = self.compute_default_fn()
if self.default not in self.objects:
self.objects.append(self.default)
self._ensure_value_is_in_objects(self.default)

def _validate(self, val):
"""
val must be None or one of the objects in self.objects.
"""
if not self.check_on_set:
self._ensure_value_is_in_objects(val)
return

if not (val in self.objects or (self.allow_None and val is None)):
self._validate_value(val)

def _validate_value(self, val):
if self.check_on_set and not (self.allow_None and val is None) and val not in self.objects:
items = []
limiter = ']'
length = 0
Expand Down Expand Up @@ -2623,16 +2618,34 @@ def compute_default(self):
self.objects.append(o)

def _validate(self, val):
self._validate_type(val)

if self.check_on_set:
self._validate_value(val)
else:
self._ensure_value_is_in_objects(val)


def _validate_type(self, val):
if (val is None and self.allow_None):
return

if not isinstance(val, list):
raise ValueError(
f"{_validate_error_prefix(self)} only takes list types, "
f"not {val!r}."
)
for o in val:
super()._validate(o)

def _validate_value(self, val):
self._validate_type(val)
if val is not None:
for o in val:
super()._validate_value(o)

def _update_state(self):
if self.check_on_set is False and self.default is not None:
for o in self.default:
self._ensure_value_is_in_objects(o)


class MultiFileSelector(ListSelector):
Expand Down
15 changes: 8 additions & 7 deletions tests/testlistselector.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def setUp(self):
super().setUp()
class P(param.Parameterized):
e = param.ListSelector(default=[5],objects=[5,6,7])
f = param.ListSelector(default=10)
f = param.ListSelector(default=[10])
h = param.ListSelector(default=None)
g = param.ListSelector(default=None,objects=[7,8])
i = param.ListSelector(default=[7],objects=[9],check_on_set=False)
Expand Down Expand Up @@ -173,16 +173,17 @@ class Q(param.Parameterized):
r = param.ListSelector(default=[6])

##########################
# CEBALERT: not sure it makes sense for ListSelector to be set to
# a non-iterable value (except None). I.e. I think this first test
# should fail.
def test_default_not_checked_to_be_iterable(self):
class Q(param.Parameterized):
r = param.ListSelector(default=6)
with pytest.raises(
ValueError,
match=re.escape("ListSelector parameter 'r' only takes list types, not 6."),
):
class Q(param.Parameterized):
r = param.ListSelector(default=6)

def test_set_checked_to_be_iterable(self):
class Q(param.Parameterized):
r = param.ListSelector(default=6,check_on_set=False)
r = param.ListSelector(default=[6],check_on_set=False)

with self.assertRaises(ValueError):
Q.r = 6
Expand Down

0 comments on commit 83e57ea

Please sign in to comment.