diff --git a/packages/python/plotly/_plotly_utils/basevalidators.py b/packages/python/plotly/_plotly_utils/basevalidators.py index 71c01b4116..e0ce3e4f2d 100644 --- a/packages/python/plotly/_plotly_utils/basevalidators.py +++ b/packages/python/plotly/_plotly_utils/basevalidators.py @@ -824,13 +824,21 @@ class IntegerValidator(BaseValidator): "dflt", "min", "max", + "extras", "arrayOk" ] }, """ def __init__( - self, plotly_name, parent_name, min=None, max=None, array_ok=False, **kwargs + self, + plotly_name, + parent_name, + min=None, + max=None, + extras=None, + array_ok=False, + **kwargs, ): super(IntegerValidator, self).__init__( plotly_name=plotly_name, parent_name=parent_name, **kwargs @@ -855,6 +863,7 @@ def __init__( else: self.has_min_max = False + self.extras = extras if extras is not None else [] self.array_ok = array_ok def description(self): @@ -878,6 +887,16 @@ def description(self): ) ) + # Extras + if self.extras: + desc = ( + desc + + ( + """ + OR exactly one of {extras} (e.g. '{eg_extra}')""" + ).format(extras=self.extras, eg_extra=self.extras[-1]) + ) + if self.array_ok: desc = ( desc @@ -891,6 +910,8 @@ def validate_coerce(self, v): if v is None: # Pass None through pass + elif v in self.extras: + return v elif self.array_ok and is_homogeneous_array(v): np = get_module("numpy") v_array = copy_to_readonly_numpy_array( @@ -917,14 +938,20 @@ def validate_coerce(self, v): v = v_array elif self.array_ok and is_simple_array(v): # Check integer type - invalid_els = [e for e in v if not isinstance(e, int)] + invalid_els = [ + e for e in v if not isinstance(e, int) and e not in self.extras + ] if invalid_els: self.raise_invalid_elements(invalid_els[:10]) # Check min/max if self.has_min_max: - invalid_els = [e for e in v if not (self.min_val <= e <= self.max_val)] + invalid_els = [ + e + for e in v + if not (self.min_val <= e <= self.max_val) and e not in self.extras + ] if invalid_els: self.raise_invalid_elements(invalid_els[:10])