Skip to content

Commit 772ae7e

Browse files
committed
Accept CSS color syntax supported by plotly.js in ColorValidator
Allow signed and exponent numbers, angle units other than deg, the none keyword, any color() color space and the transparent keyword. These are all accepted by plotly.js 4 but were rejected by the Python validator.
1 parent 84498cc commit 772ae7e

2 files changed

Lines changed: 34 additions & 9 deletions

File tree

‎_plotly_utils/basevalidators.py‎

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,13 +1138,24 @@ class ColorValidator(BaseValidator):
11381138
},
11391139
"""
11401140

1141-
re_spaces_to_remove = re.compile(r"(?<!(\d|%|g)) | (?!\d)")
1142-
11431141
re_hex = re.compile(
11441142
r"#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})"
11451143
)
1144+
1145+
# A CSS color function argument: a number (which may be signed or use an
1146+
# exponent) with an optional percent sign or angle unit, or `none`.
1147+
_re_css_value = (
1148+
r"(?:[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?(?:%|deg|grad|rad|turn)?|none)"
1149+
)
1150+
_re_css_sep = r"(?:\s*,\s*|\s+)"
1151+
_re_css_alpha_sep = r"(?:\s*[,/]\s*|\s+)"
11461152
re_rgb_etc = re.compile(
1147-
r"((rgb|hsl)a?|hwb|(ok)?(lab|lch))\([\d.]+(%|deg)?([ ,] ?[\d.]+%?){2}([ /,] ?[\d.]+%?)?\)|color\([\w-]+([ ,] ?[\d.]+){3,4}\)"
1153+
r"(?:(?:rgb|hsl)a?|hwb|(?:ok)?(?:lab|lch))\s*\(\s*"
1154+
rf"{_re_css_value}{_re_css_sep}{_re_css_value}{_re_css_sep}{_re_css_value}"
1155+
rf"(?:{_re_css_alpha_sep}{_re_css_value})?\s*\)"
1156+
r"|color\s*\(\s*[a-z][\w-]*"
1157+
rf"(?:{_re_css_sep}{_re_css_value}){{3}}"
1158+
rf"(?:{_re_css_alpha_sep}{_re_css_value})?\s*\)"
11481159
)
11491160
re_ddk = re.compile(r"var\(\-\-.*\)")
11501161

@@ -1290,6 +1301,7 @@ class ColorValidator(BaseValidator):
12901301
"teal",
12911302
"thistle",
12921303
"tomato",
1304+
"transparent",
12931305
"turquoise",
12941306
"violet",
12951307
"wheat",
@@ -1443,12 +1455,7 @@ def perform_validate_coerce(v, allow_number=None):
14431455
# If not allow_numbers then value must be a string
14441456
return None
14451457
else:
1446-
# Remove spaces so regexes don't need to bother with them.
1447-
# Don't remove spaces between two digits, though.
1448-
v_normalized = v.strip()
1449-
v_normalized = re.sub(" +", " ", v_normalized)
1450-
v_normalized = re.sub(ColorValidator.re_spaces_to_remove, "", v_normalized)
1451-
v_normalized = v_normalized.lower()
1458+
v_normalized = v.strip().lower()
14521459

14531460
# if ColorValidator.re_hex.fullmatch(v_normalized):
14541461
if fullmatch(ColorValidator.re_hex, v_normalized):

‎tests/test_plotly_utils/validators/test_color_validator.py‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ def validator_aok_colorscale():
5757
"lab(70 15 50)",
5858
"lch(70 15 180)",
5959
"color(display-p3 1 0 0)",
60+
"color(srgb 1 0 0)",
61+
"color(a98-rgb 1 0 0 / 0.5)",
62+
"lab(50% -40 59.5)",
63+
"oklab(0.6 0.1 -0.05)",
64+
"lch(52% 72 -30)",
65+
"hsl(-30, 50%, 50%)",
66+
"hsl(0.5turn 60% 40%)",
67+
"hsl(1rad 60% 40%)",
68+
"hsl(none 60% 40%)",
69+
"rgb(255 0 0 / none)",
70+
"rgb(1e2, 0, 0)",
71+
"transparent",
6072
]
6173

6274
INVALID_COLORS_WRONG_TYPE = [
@@ -72,6 +84,12 @@ def validator_aok_colorscale():
7284
"hsl(0, 1%0000%, 50%)",
7385
"hsv(0, 100%, 100%)",
7486
"hsva(0, 100%, 100%, 50%)",
87+
"currentcolor",
88+
"rgb(255, 0)",
89+
"rgb(255 0 0 /)",
90+
"rgb(1-2 3 4)",
91+
"color(1 0 0)",
92+
"color(srgb 1 0)",
7593
]
7694

7795

0 commit comments

Comments
 (0)