Skip to content

Commit ccbd940

Browse files
author
Jon M. Mease
committed
Add support for strict option to in string validator
This allows numbers to be specified for non-strict string properties
1 parent d537452 commit ccbd940

File tree

2 files changed

+50
-12
lines changed

2 files changed

+50
-12
lines changed

_plotly_utils/basevalidators.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ def __init__(self,
667667
super().__init__(
668668
plotly_name=plotly_name, parent_name=parent_name, **kwargs)
669669
self.no_blank = no_blank
670-
self.strict = strict # Not implemented. We're always strict
670+
self.strict = strict
671671
self.array_ok = array_ok
672672
self.values = values
673673

@@ -694,6 +694,10 @@ def description(self):
694694
desc = desc + """
695695
- A string"""
696696

697+
if not self.strict:
698+
desc = desc + """
699+
- A number that will be converted to a string"""
700+
697701
if self.array_ok:
698702
desc = desc + """
699703
- A tuple, list, or one-dimensional numpy array of the above"""
@@ -706,12 +710,13 @@ def validate_coerce(self, v):
706710
pass
707711
elif self.array_ok and is_array(v):
708712

709-
# Make sure all elements are strings. Is there a more efficient
710-
# way to do this in numpy?
711-
invalid_els = [e for e in v if not isinstance(e, str)]
712-
if invalid_els:
713-
self.raise_invalid_elements(invalid_els)
713+
# If strict, make sure all elements are strings.
714+
if self.strict:
715+
invalid_els = [e for e in v if not isinstance(e, str)]
716+
if invalid_els:
717+
self.raise_invalid_elements(invalid_els)
714718

719+
# If not strict, let numpy cast elements to strings
715720
v = copy_to_readonly_numpy_array(v, dtype='unicode')
716721

717722
if self.no_blank:
@@ -725,8 +730,15 @@ def validate_coerce(self, v):
725730
if invalid_els:
726731
self.raise_invalid_elements(invalid_els)
727732
else:
728-
if not isinstance(v, str):
729-
self.raise_invalid_val(v)
733+
if self.strict:
734+
if not isinstance(v, str):
735+
self.raise_invalid_val(v)
736+
else:
737+
if not isinstance(v, (str, int, float)):
738+
self.raise_invalid_val(v)
739+
740+
# Convert value to a string
741+
v = str(v)
730742

731743
if self.no_blank and len(v) == 0:
732744
self.raise_invalid_val(v)

_plotly_utils/tests/validators/test_string_validator.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,14 @@ def validator_no_blanks():
2020
return StringValidator('prop', 'parent', no_blank=True)
2121

2222

23+
@pytest.fixture()
24+
def validator_strict():
25+
return StringValidator('prop', 'parent', strict=True)
26+
27+
2328
@pytest.fixture
2429
def validator_aok():
25-
return StringValidator('prop', 'parent', array_ok=True)
30+
return StringValidator('prop', 'parent', array_ok=True, strict=True)
2631

2732

2833
@pytest.fixture
@@ -37,16 +42,18 @@ def validator_no_blanks_aok():
3742

3843
# Array not ok
3944
# ------------
45+
# Not strict
4046
# ### Acceptance ###
4147
@pytest.mark.parametrize('val',
42-
['bar', 'HELLO!!!', 'world!@#$%^&*()', ''])
48+
['bar', 234, np.nan,
49+
'HELLO!!!', 'world!@#$%^&*()', ''])
4350
def test_acceptance(val, validator: StringValidator):
44-
assert validator.validate_coerce(val) == val
51+
assert validator.validate_coerce(val) == str(val)
4552

4653

4754
# ### Rejection by value ###
4855
@pytest.mark.parametrize('val',
49-
[(), [], [1, 2, 3], set(), np.nan, np.pi])
56+
[(), [], [1, 2, 3], set()])
5057
def test_rejection(val, validator: StringValidator):
5158
with pytest.raises(ValueError) as validation_failure:
5259
validator.validate_coerce(val)
@@ -88,6 +95,25 @@ def test_rejection_no_blanks(val, validator_no_blanks: StringValidator):
8895
assert 'A non-empty string' in str(validation_failure.value)
8996

9097

98+
# Strict
99+
# ------
100+
# ### Acceptance ###
101+
@pytest.mark.parametrize('val',
102+
['bar', 'HELLO!!!', 'world!@#$%^&*()', ''])
103+
def test_acceptance_strict(val, validator_strict: StringValidator):
104+
assert validator_strict.validate_coerce(val) == val
105+
106+
107+
# ### Rejection by value ###
108+
@pytest.mark.parametrize('val',
109+
[(), [], [1, 2, 3], set(), np.nan, np.pi, 23])
110+
def test_rejection_strict(val, validator_strict: StringValidator):
111+
with pytest.raises(ValueError) as validation_failure:
112+
validator_strict.validate_coerce(val)
113+
114+
assert 'Invalid value' in str(validation_failure.value)
115+
116+
91117
# Array ok
92118
# --------
93119
# ### Acceptance ###

0 commit comments

Comments
 (0)