From 6858824cb5055254670ed55395edbe3624bd88a5 Mon Sep 17 00:00:00 2001 From: Jon Mease Date: Tue, 6 Nov 2018 15:35:30 -0500 Subject: [PATCH 1/3] Added failing test cases --- .../validators/test_infoarray_validator.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/_plotly_utils/tests/validators/test_infoarray_validator.py b/_plotly_utils/tests/validators/test_infoarray_validator.py index 84bd284c418..5da739fd2f2 100644 --- a/_plotly_utils/tests/validators/test_infoarray_validator.py +++ b/_plotly_utils/tests/validators/test_infoarray_validator.py @@ -26,6 +26,14 @@ def validator_number3_free(): {'valType': 'number', 'min': 0, 'max': 1}], free_length=True) +@pytest.fixture() +def validator_any3_free(): + return InfoArrayValidator('prop', 'parent', items=[ + {'valType': 'any'}, + {'valType': 'any'}, + {'valType': 'any'}], free_length=True) + + @pytest.fixture() def validator_number2_2d(): return InfoArrayValidator('prop', 'parent', items=[ @@ -219,6 +227,27 @@ def test_validator_rejection_number3_free_element_value(val, first_invalid_ind, first_invalid_ind=first_invalid_ind)) in str(validation_failure.value) +# Any3 Tests (free_length=True) +# -------------------------------- +# ### Acceptance ### +@pytest.mark.parametrize('val', [ + [1, 0, 'Hello'], + (False, 0.99), + np.array([0.1, 0.99]), + [0], [], + [['a', 'list']], + [['a', 'list'], 0], + [0, ['a', 'list'], 1], +]) +def test_validator_acceptance_any3_free(val, validator_any3_free): + coerce_val = validator_any3_free.validate_coerce(val) + assert coerce_val == list(val) + + # Compute expected + expected = tuple(tuple(el) if isinstance(el, list) else el for el in val) + assert validator_any3_free.present(coerce_val) == expected + + # Number2 2D # ---------- # ### Acceptance ### From fb581499ff83a15209e3f1f9afb013e588d1414d Mon Sep 17 00:00:00 2001 From: Jon Mease Date: Tue, 6 Nov 2018 15:36:49 -0500 Subject: [PATCH 2/3] Only perform 2D validation if 2D array is allowed --- _plotly_utils/basevalidators.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/_plotly_utils/basevalidators.py b/_plotly_utils/basevalidators.py index 58f769bc4eb..177248f28ff 100644 --- a/_plotly_utils/basevalidators.py +++ b/_plotly_utils/basevalidators.py @@ -1808,10 +1808,7 @@ def validate_coerce(self, v): is_v_2d = v and is_array(v[0]) - if is_v_2d: - if self.dimensions == 1: - self.raise_invalid_val(orig_v) - else: # self.dimensions is '1-2' or 2 + if is_v_2d and self.dimensions in ('1-2', 2): if is_array(self.items): # e.g. 2D list as parcoords.dimensions.constraintrange # check that all items are there for each nested element From 05e66339a1d205f909fbcf217302fea6e057e650 Mon Sep 17 00:00:00 2001 From: Jon Mease Date: Tue, 6 Nov 2018 15:37:48 -0500 Subject: [PATCH 3/3] Fix indentation omitted (for clarity) from previous commit --- _plotly_utils/basevalidators.py | 44 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/_plotly_utils/basevalidators.py b/_plotly_utils/basevalidators.py index 177248f28ff..df6ecc9da47 100644 --- a/_plotly_utils/basevalidators.py +++ b/_plotly_utils/basevalidators.py @@ -1809,28 +1809,28 @@ def validate_coerce(self, v): is_v_2d = v and is_array(v[0]) if is_v_2d and self.dimensions in ('1-2', 2): - if is_array(self.items): - # e.g. 2D list as parcoords.dimensions.constraintrange - # check that all items are there for each nested element - for i, row in enumerate(v): - # Check row length - if not is_array(row) or len(row) != len(self.items): - self.raise_invalid_val(orig_v[i], [i]) - - for j, validator in enumerate(self.item_validators): - row[j] = self.validate_element_with_indexed_name( - v[i][j], validator, [i, j]) - else: - # e.g. 2D list as layout.grid.subplots - # check that all elements match individual validator - validator = self.item_validators[0] - for i, row in enumerate(v): - if not is_array(row): - self.raise_invalid_val(orig_v[i], [i]) - - for j, el in enumerate(row): - row[j] = self.validate_element_with_indexed_name( - el, validator, [i, j]) + if is_array(self.items): + # e.g. 2D list as parcoords.dimensions.constraintrange + # check that all items are there for each nested element + for i, row in enumerate(v): + # Check row length + if not is_array(row) or len(row) != len(self.items): + self.raise_invalid_val(orig_v[i], [i]) + + for j, validator in enumerate(self.item_validators): + row[j] = self.validate_element_with_indexed_name( + v[i][j], validator, [i, j]) + else: + # e.g. 2D list as layout.grid.subplots + # check that all elements match individual validator + validator = self.item_validators[0] + for i, row in enumerate(v): + if not is_array(row): + self.raise_invalid_val(orig_v[i], [i]) + + for j, el in enumerate(row): + row[j] = self.validate_element_with_indexed_name( + el, validator, [i, j]) elif v and self.dimensions == 2: # e.g. 1D list passed as layout.grid.subplots self.raise_invalid_val(orig_v[0], [0])