Skip to content

pydantic.color

Color definitions are used as per the CSS3 CSS Color Module Level 3 specification.

A few colors have multiple names referring to the sames colors, eg. grey and gray or aqua and cyan.

In these cases the last color when sorted alphabetically takes preferences, eg. Color((0, 255, 255)).as_named() == 'cyan' because "cyan" comes after "aqua".

Deprecated

The Color class is deprecated, use pydantic_extra_types instead. See pydantic-extra-types.Color for more information.

Color

Color(value)

Bases: _repr.Representation

Represents a color.

Source code in pydantic/color.py
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def __init__(self, value: ColorType) -> None:
    self._rgba: RGBA
    self._original: ColorType
    if isinstance(value, (tuple, list)):
        self._rgba = parse_tuple(value)
    elif isinstance(value, str):
        self._rgba = parse_str(value)
    elif isinstance(value, Color):
        self._rgba = value._rgba
        value = value._original
    else:
        raise PydanticCustomError(
            'color_error', 'value is not a valid color: value must be a tuple, list or string'
        )

    # if we've got here value must be a valid color
    self._original = value

as_hex

as_hex()

Returns the hexadecimal representation of the color.

Hex string representing the color can be 3, 4, 6, or 8 characters depending on whether the string a "short" representation of the color is possible and whether there's an alpha channel.

Returns:

Type Description
str

The hexadecimal representation of the color.

Source code in pydantic/color.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
def as_hex(self) -> str:
    """Returns the hexadecimal representation of the color.

    Hex string representing the color can be 3, 4, 6, or 8 characters depending on whether the string
    a "short" representation of the color is possible and whether there's an alpha channel.

    Returns:
        The hexadecimal representation of the color.
    """
    values = [float_to_255(c) for c in self._rgba[:3]]
    if self._rgba.alpha is not None:
        values.append(float_to_255(self._rgba.alpha))

    as_hex = ''.join(f'{v:02x}' for v in values)
    if all(c in repeat_colors for c in values):
        as_hex = ''.join(as_hex[c] for c in range(0, len(as_hex), 2))
    return '#' + as_hex

as_hsl

as_hsl()

Color as an hsl(<h>, <s>, <l>) or hsl(<h>, <s>, <l>, <a>) string.

Source code in pydantic/color.py
191
192
193
194
195
196
197
198
def as_hsl(self) -> str:
    """Color as an `hsl(<h>, <s>, <l>)` or `hsl(<h>, <s>, <l>, <a>)` string."""
    if self._rgba.alpha is None:
        h, s, li = self.as_hsl_tuple(alpha=False)  # type: ignore
        return f'hsl({h * 360:0.0f}, {s:0.0%}, {li:0.0%})'
    else:
        h, s, li, a = self.as_hsl_tuple(alpha=True)  # type: ignore
        return f'hsl({h * 360:0.0f}, {s:0.0%}, {li:0.0%}, {round(a, 2)})'

as_hsl_tuple

as_hsl_tuple(*, alpha=None)

Returns the color as an HSL or HSLA tuple.

Parameters:

Name Type Description Default
alpha Optional[bool]

Whether to include the alpha channel.

  • None (default): Include the alpha channel only if it's set (e.g. not None).
  • True: Always include alpha.
  • False: Always omit alpha.
None

Returns:

Type Description
HslColorTuple

The color as a tuple of hue, saturation, lightness, and alpha (if included). All elements are in the range 0 to 1.

Note

This is HSL as used in HTML and most other places, not HLS as used in Python's colorsys.

Source code in pydantic/color.py
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
def as_hsl_tuple(self, *, alpha: Optional[bool] = None) -> HslColorTuple:
    """Returns the color as an HSL or HSLA tuple.

    Args:
        alpha: Whether to include the alpha channel.

            - `None` (default): Include the alpha channel only if it's set (e.g. not `None`).
            - `True`: Always include alpha.
            - `False`: Always omit alpha.

    Returns:
        The color as a tuple of hue, saturation, lightness, and alpha (if included).
            All elements are in the range 0 to 1.

    Note:
        This is HSL as used in HTML and most other places, not HLS as used in Python's `colorsys`.
    """
    h, l, s = rgb_to_hls(self._rgba.r, self._rgba.g, self._rgba.b)  # noqa: E741
    if alpha is None:
        if self._rgba.alpha is None:
            return h, s, l
        else:
            return h, s, l, self._alpha_float()
    if alpha:
        return h, s, l, self._alpha_float()
    else:
        # alpha is False
        return h, s, l

as_named

as_named(*, fallback=False)

Returns the name of the color if it can be found in COLORS_BY_VALUE dictionary, otherwise returns the hexadecimal representation of the color or raises ValueError.

Parameters:

Name Type Description Default
fallback bool

If True, falls back to returning the hexadecimal representation of the color instead of raising a ValueError when no named color is found.

False

Returns:

Type Description
str

The name of the color, or the hexadecimal representation of the color.

Raises:

Type Description
ValueError

When no named color is found and fallback is False.

Source code in pydantic/color.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
def as_named(self, *, fallback: bool = False) -> str:
    """Returns the name of the color if it can be found in `COLORS_BY_VALUE` dictionary,
    otherwise returns the hexadecimal representation of the color or raises `ValueError`.

    Args:
        fallback: If True, falls back to returning the hexadecimal representation of
            the color instead of raising a ValueError when no named color is found.

    Returns:
        The name of the color, or the hexadecimal representation of the color.

    Raises:
        ValueError: When no named color is found and fallback is `False`.
    """
    if self._rgba.alpha is None:
        rgb = cast(Tuple[int, int, int], self.as_rgb_tuple())
        try:
            return COLORS_BY_VALUE[rgb]
        except KeyError as e:
            if fallback:
                return self.as_hex()
            else:
                raise ValueError('no named color found, use fallback=True, as_hex() or as_rgb()') from e
    else:
        return self.as_hex()

as_rgb

as_rgb()

Color as an rgb(<r>, <g>, <b>) or rgba(<r>, <g>, <b>, <a>) string.

Source code in pydantic/color.py
155
156
157
158
159
160
161
162
163
def as_rgb(self) -> str:
    """Color as an `rgb(<r>, <g>, <b>)` or `rgba(<r>, <g>, <b>, <a>)` string."""
    if self._rgba.alpha is None:
        return f'rgb({float_to_255(self._rgba.r)}, {float_to_255(self._rgba.g)}, {float_to_255(self._rgba.b)})'
    else:
        return (
            f'rgba({float_to_255(self._rgba.r)}, {float_to_255(self._rgba.g)}, {float_to_255(self._rgba.b)}, '
            f'{round(self._alpha_float(), 2)})'
        )

as_rgb_tuple

as_rgb_tuple(*, alpha=None)

Returns the color as an RGB or RGBA tuple.

Parameters:

Name Type Description Default
alpha Optional[bool]

Whether to include the alpha channel. There are three options for this input:

  • None (default): Include alpha only if it's set. (e.g. not None)
  • True: Always include alpha.
  • False: Always omit alpha.
None

Returns:

Type Description
ColorTuple

A tuple that contains the values of the red, green, and blue channels in the range 0 to 255. If alpha is included, it is in the range 0 to 1.

Source code in pydantic/color.py
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
def as_rgb_tuple(self, *, alpha: Optional[bool] = None) -> ColorTuple:
    """Returns the color as an RGB or RGBA tuple.

    Args:
        alpha: Whether to include the alpha channel. There are three options for this input:

            - `None` (default): Include alpha only if it's set. (e.g. not `None`)
            - `True`: Always include alpha.
            - `False`: Always omit alpha.

    Returns:
        A tuple that contains the values of the red, green, and blue channels in the range 0 to 255.
            If alpha is included, it is in the range 0 to 1.
    """
    r, g, b = (float_to_255(c) for c in self._rgba[:3])
    if alpha is None:
        if self._rgba.alpha is None:
            return r, g, b
        else:
            return r, g, b, self._alpha_float()
    elif alpha:
        return r, g, b, self._alpha_float()
    else:
        # alpha is False
        return r, g, b

original

original()

Original value passed to Color.

Source code in pydantic/color.py
107
108
109
def original(self) -> ColorType:
    """Original value passed to `Color`."""
    return self._original

float_to_255

float_to_255(c)

Converts a float value between 0 and 1 (inclusive) to an integer between 0 and 255 (inclusive).

Parameters:

Name Type Description Default
c float

The float value to be converted. Must be between 0 and 1 (inclusive).

required

Returns:

Type Description
int

The integer equivalent of the given float value rounded to the nearest whole number.

Raises:

Type Description
ValueError

If the given float value is outside the acceptable range of 0 to 1 (inclusive).

Source code in pydantic/color.py
438
439
440
441
442
443
444
445
446
447
448
449
450
def float_to_255(c: float) -> int:
    """Converts a float value between 0 and 1 (inclusive) to an integer between 0 and 255 (inclusive).

    Args:
        c: The float value to be converted. Must be between 0 and 1 (inclusive).

    Returns:
        The integer equivalent of the given float value rounded to the nearest whole number.

    Raises:
        ValueError: If the given float value is outside the acceptable range of 0 to 1 (inclusive).
    """
    return int(round(c * 255))

ints_to_rgba

ints_to_rgba(r, g, b, alpha=None)

Converts integer or string values for RGB color and an optional alpha value to an RGBA object.

Parameters:

Name Type Description Default
r Union[int, str]

An integer or string representing the red color value.

required
g Union[int, str]

An integer or string representing the green color value.

required
b Union[int, str]

An integer or string representing the blue color value.

required
alpha Optional[float]

A float representing the alpha value. Defaults to None.

None

Returns:

Type Description
RGBA

An instance of the RGBA class with the corresponding color and alpha values.

Source code in pydantic/color.py
338
339
340
341
342
343
344
345
346
347
348
349
350
def ints_to_rgba(r: Union[int, str], g: Union[int, str], b: Union[int, str], alpha: Optional[float] = None) -> RGBA:
    """Converts integer or string values for RGB color and an optional alpha value to an `RGBA` object.

    Args:
        r: An integer or string representing the red color value.
        g: An integer or string representing the green color value.
        b: An integer or string representing the blue color value.
        alpha: A float representing the alpha value. Defaults to None.

    Returns:
        An instance of the `RGBA` class with the corresponding color and alpha values.
    """
    return RGBA(parse_color_value(r), parse_color_value(g), parse_color_value(b), parse_float_alpha(alpha))

parse_color_value

parse_color_value(value, max_val=255)

Parse the color value provided and return a number between 0 and 1.

Parameters:

Name Type Description Default
value Union[int, str]

An integer or string color value.

required
max_val int

Maximum range value. Defaults to 255.

255

Raises:

Type Description
PydanticCustomError

If the value is not a valid color.

Returns:

Type Description
float

A number between 0 and 1.

Source code in pydantic/color.py
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
def parse_color_value(value: Union[int, str], max_val: int = 255) -> float:
    """Parse the color value provided and return a number between 0 and 1.

    Args:
        value: An integer or string color value.
        max_val: Maximum range value. Defaults to 255.

    Raises:
        PydanticCustomError: If the value is not a valid color.

    Returns:
        A number between 0 and 1.
    """
    try:
        color = float(value)
    except ValueError:
        raise PydanticCustomError('color_error', 'value is not a valid color: color values must be a valid number')
    if 0 <= color <= max_val:
        return color / max_val
    else:
        raise PydanticCustomError(
            'color_error',
            'value is not a valid color: color values must be in the range 0 to {max_val}',
            {'max_val': max_val},
        )

parse_float_alpha

parse_float_alpha(value)

Parse an alpha value checking it's a valid float in the range 0 to 1.

Parameters:

Name Type Description Default
value Union[None, str, float, int]

The input value to parse.

required

Returns:

Type Description
Optional[float]

The parsed value as a float, or None if the value was None or equal 1.

Raises:

Type Description
PydanticCustomError

If the input value cannot be successfully parsed as a float in the expected range.

Source code in pydantic/color.py
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
def parse_float_alpha(value: Union[None, str, float, int]) -> Optional[float]:
    """Parse an alpha value checking it's a valid float in the range 0 to 1.

    Args:
        value: The input value to parse.

    Returns:
        The parsed value as a float, or `None` if the value was None or equal 1.

    Raises:
        PydanticCustomError: If the input value cannot be successfully parsed as a float in the expected range.
    """
    if value is None:
        return None
    try:
        if isinstance(value, str) and value.endswith('%'):
            alpha = float(value[:-1]) / 100
        else:
            alpha = float(value)
    except ValueError:
        raise PydanticCustomError('color_error', 'value is not a valid color: alpha values must be a valid float')

    if _utils.almost_equal_floats(alpha, 1):
        return None
    elif 0 <= alpha <= 1:
        return alpha
    else:
        raise PydanticCustomError('color_error', 'value is not a valid color: alpha values must be in the range 0 to 1')

parse_hsl

parse_hsl(h, h_units, sat, light, alpha=None)

Parse raw hue, saturation, lightness, and alpha values and convert to RGBA.

Parameters:

Name Type Description Default
h str

The hue value.

required
h_units str

The unit for hue value.

required
sat str

The saturation value.

required
light str

The lightness value.

required
alpha Optional[float]

Alpha value.

None

Returns:

Type Description
RGBA

An instance of RGBA.

Source code in pydantic/color.py
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
def parse_hsl(h: str, h_units: str, sat: str, light: str, alpha: Optional[float] = None) -> RGBA:
    """Parse raw hue, saturation, lightness, and alpha values and convert to RGBA.

    Args:
        h: The hue value.
        h_units: The unit for hue value.
        sat: The saturation value.
        light: The lightness value.
        alpha: Alpha value.

    Returns:
        An instance of `RGBA`.
    """
    s_value, l_value = parse_color_value(sat, 100), parse_color_value(light, 100)

    h_value = float(h)
    if h_units in {None, 'deg'}:
        h_value = h_value % 360 / 360
    elif h_units == 'rad':
        h_value = h_value % rads / rads
    else:
        # turns
        h_value = h_value % 1

    r, g, b = hls_to_rgb(h_value, l_value, s_value)
    return RGBA(r, g, b, parse_float_alpha(alpha))

parse_str

parse_str(value)

Parse a string representing a color to an RGBA tuple.

Possible formats for the input string include:

  • named color, see COLORS_BY_NAME
  • hex short eg. <prefix>fff (prefix can be #, 0x or nothing)
  • hex long eg. <prefix>ffffff (prefix can be #, 0x or nothing)
  • rgb(<r>, <g>, <b>)
  • rgba(<r>, <g>, <b>, <a>)

Parameters:

Name Type Description Default
value str

A string representing a color.

required

Returns:

Type Description
RGBA

An RGBA tuple parsed from the input string.

Raises:

Type Description
ValueError

If the input string cannot be parsed to an RGBA tuple.

Source code in pydantic/color.py
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
def parse_str(value: str) -> RGBA:
    """Parse a string representing a color to an RGBA tuple.

    Possible formats for the input string include:

    * named color, see `COLORS_BY_NAME`
    * hex short eg. `<prefix>fff` (prefix can be `#`, `0x` or nothing)
    * hex long eg. `<prefix>ffffff` (prefix can be `#`, `0x` or nothing)
    * `rgb(<r>, <g>, <b>)`
    * `rgba(<r>, <g>, <b>, <a>)`

    Args:
        value: A string representing a color.

    Returns:
        An `RGBA` tuple parsed from the input string.

    Raises:
        ValueError: If the input string cannot be parsed to an RGBA tuple.
    """
    value_lower = value.lower()
    try:
        r, g, b = COLORS_BY_NAME[value_lower]
    except KeyError:
        pass
    else:
        return ints_to_rgba(r, g, b, None)

    m = re.fullmatch(r_hex_short, value_lower)
    if m:
        *rgb, a = m.groups()
        r, g, b = (int(v * 2, 16) for v in rgb)
        if a:
            alpha: Optional[float] = int(a * 2, 16) / 255
        else:
            alpha = None
        return ints_to_rgba(r, g, b, alpha)

    m = re.fullmatch(r_hex_long, value_lower)
    if m:
        *rgb, a = m.groups()
        r, g, b = (int(v, 16) for v in rgb)
        if a:
            alpha = int(a, 16) / 255
        else:
            alpha = None
        return ints_to_rgba(r, g, b, alpha)

    m = re.fullmatch(r_rgb, value_lower) or re.fullmatch(r_rgb_v4_style, value_lower)
    if m:
        return ints_to_rgba(*m.groups())  # type: ignore

    m = re.fullmatch(r_hsl, value_lower) or re.fullmatch(r_hsl_v4_style, value_lower)
    if m:
        return parse_hsl(*m.groups())  # type: ignore

    raise PydanticCustomError('color_error', 'value is not a valid color: string not recognised as a valid color')

parse_tuple

parse_tuple(value)

Parse a tuple or list to get RGBA values.

Parameters:

Name Type Description Default
value Tuple[Any, ...]

A tuple or list.

required

Returns:

Type Description
RGBA

An RGBA tuple parsed from the input tuple.

Raises:

Type Description
PydanticCustomError

If tuple is not valid.

Source code in pydantic/color.py
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
def parse_tuple(value: Tuple[Any, ...]) -> RGBA:
    """Parse a tuple or list to get RGBA values.

    Args:
        value: A tuple or list.

    Returns:
        An `RGBA` tuple parsed from the input tuple.

    Raises:
        PydanticCustomError: If tuple is not valid.
    """
    if len(value) == 3:
        r, g, b = (parse_color_value(v) for v in value)
        return RGBA(r, g, b, None)
    elif len(value) == 4:
        r, g, b = (parse_color_value(v) for v in value[:3])
        return RGBA(r, g, b, parse_float_alpha(value[3]))
    else:
        raise PydanticCustomError('color_error', 'value is not a valid color: tuples must have length 3 or 4')