diff --git a/CHANGELOG.md b/CHANGELOG.md index 20c880922af..b43a738776c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## UNRELEASED + +### Updated +- Fixed a bug in integer validation of arrays that threw an error when an array contained a mix of strings and integers. + ## [5.23.0] - 2024-07-23 ### Updated diff --git a/packages/python/plotly/_plotly_utils/basevalidators.py b/packages/python/plotly/_plotly_utils/basevalidators.py index e0ce3e4f2de..21731afad43 100644 --- a/packages/python/plotly/_plotly_utils/basevalidators.py +++ b/packages/python/plotly/_plotly_utils/basevalidators.py @@ -950,7 +950,8 @@ def validate_coerce(self, v): invalid_els = [ e for e in v - if not (self.min_val <= e <= self.max_val) and e not in self.extras + if not (isinstance(e, int) and self.min_val <= e <= self.max_val) + and e not in self.extras ] if invalid_els: diff --git a/packages/python/plotly/_plotly_utils/tests/validators/test_integer_validator.py b/packages/python/plotly/_plotly_utils/tests/validators/test_integer_validator.py index 8b7cb1dbf48..9a01fde7e41 100644 --- a/packages/python/plotly/_plotly_utils/tests/validators/test_integer_validator.py +++ b/packages/python/plotly/_plotly_utils/tests/validators/test_integer_validator.py @@ -33,6 +33,18 @@ def validator_aok(request): return IntegerValidator("prop", "parent", min=-2, max=10, array_ok=True) +@pytest.fixture +def validator_extras(): + return IntegerValidator("prop", "parent", min=-2, max=10, extras=["normal", "bold"]) + + +@pytest.fixture +def validator_extras_aok(): + return IntegerValidator( + "prop", "parent", min=-2, max=10, array_ok=True, extras=["normal", "bold"] + ) + + # ### Acceptance ### @pytest.mark.parametrize("val", [1, -19, 0, -1234]) def test_acceptance(val, validator): @@ -57,6 +69,27 @@ def test_acceptance_min_max(val, validator_min_max): assert validator_min_max.validate_coerce(val) == approx(val) +# With extras +@pytest.mark.parametrize("val", ["normal", "bold", 10, -2]) +def test_acceptance_extras(val, validator_extras): + assert validator_extras.validate_coerce(val) == val + + +# Test extras for array_ok +@pytest.mark.parametrize("val", [[10, "normal", "bold"], ["normal"], [10, -2], [5]]) +def test_acceptance_extras_array(val, validator_extras_aok): + assert validator_extras_aok.validate_coerce(val) == val + + +# Test rejection by extras +@pytest.mark.parametrize("val", ["invalid value", "different invalid value", -3, 11]) +def test_rejection_extras(val, validator_extras): + with pytest.raises(ValueError) as validation_failure: + validator_extras.validate_coerce(val) + + assert "Invalid value" in str(validation_failure.value) + + @pytest.mark.parametrize( "val", [-1.01, -10, 2.1, 3, np.iinfo(int).max, np.iinfo(int).min] )