Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/webcolors/_normalization.py: 38%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

21 statements  

1""" 

2Normalization utilities for color values. 

3 

4""" 

5 

6# SPDX-License-Identifier: BSD-3-Clause 

7 

8from ._definitions import _HEX_COLOR_RE 

9from ._types import IntegerRGB, IntTuple, PercentRGB, PercentTuple 

10 

11 

12def normalize_hex(hex_value: str) -> str: 

13 """ 

14 Normalize a hexadecimal color value to a string consisting of the character `#` 

15 followed by six lowercase hexadecimal digits (what HTML5 terms a "valid lowercase 

16 simple color"). 

17 

18 If the supplied value cannot be interpreted as a hexadecimal color value, 

19 :exc:`ValueError` is raised. See :ref:`the conventions used by this module 

20 <conventions>` for information on acceptable formats for hexadecimal values. 

21 

22 Examples: 

23 

24 .. doctest:: 

25 

26 >>> normalize_hex("#0099cc") 

27 '#0099cc' 

28 >>> normalize_hex("#0099CC") 

29 '#0099cc' 

30 >>> normalize_hex("#09c") 

31 '#0099cc' 

32 >>> normalize_hex("#09C") 

33 '#0099cc' 

34 >>> normalize_hex("#0099gg") 

35 Traceback (most recent call last): 

36 ... 

37 ValueError: '#0099gg' is not a valid hexadecimal color value. 

38 >>> normalize_hex("0099cc") 

39 Traceback (most recent call last): 

40 ... 

41 ValueError: '0099cc' is not a valid hexadecimal color value. 

42 

43 :param hex_value: The hexadecimal color value to normalize. 

44 :raises ValueError: when the input is not a valid hexadecimal color value. 

45 

46 """ 

47 if (match := _HEX_COLOR_RE.match(hex_value)) is None: 

48 raise ValueError(f'"{hex_value}" is not a valid hexadecimal color value.') 

49 hex_digits = match.group(1) 

50 if len(hex_digits) == 3: 

51 hex_digits = "".join(2 * s for s in hex_digits) 

52 return f"#{hex_digits.lower()}" 

53 

54 

55def _normalize_integer_rgb(value: int) -> int: 

56 """ 

57 Internal normalization function for clipping integer values into the permitted 

58 range (0-255, inclusive). 

59 

60 """ 

61 return 0 if value < 0 else 255 if value > 255 else value 

62 

63 

64def normalize_integer_triplet(rgb_triplet: IntTuple) -> IntegerRGB: 

65 """ 

66 Normalize an integer ``rgb()`` triplet so that all values are within the range 

67 0..255. 

68 

69 Examples: 

70 

71 .. doctest:: 

72 

73 >>> normalize_integer_triplet((128, 128, 128)) 

74 IntegerRGB(red=128, green=128, blue=128) 

75 >>> normalize_integer_triplet((0, 0, 0)) 

76 IntegerRGB(red=0, green=0, blue=0) 

77 >>> normalize_integer_triplet((255, 255, 255)) 

78 IntegerRGB(red=255, green=255, blue=255) 

79 >>> normalize_integer_triplet((270, -20, -0)) 

80 IntegerRGB(red=255, green=0, blue=0) 

81 

82 :param rgb_triplet: The percentage `rgb()` triplet to normalize. 

83 

84 """ 

85 return IntegerRGB._make(_normalize_integer_rgb(value) for value in rgb_triplet) 

86 

87 

88def _normalize_percent_rgb(value: str) -> str: 

89 """ 

90 Internal normalization function for clipping percent values into the permitted 

91 range (0%-100%, inclusive). 

92 

93 """ 

94 value = value.split("%")[0] 

95 percent = float(value) if "." in value else int(value) 

96 

97 return "0%" if percent < 0 else "100%" if percent > 100 else f"{percent}%" 

98 

99 

100def normalize_percent_triplet(rgb_triplet: PercentTuple) -> PercentRGB: 

101 """ 

102 Normalize a percentage ``rgb()`` triplet so that all values are within the range 

103 0%..100%. 

104 

105 Examples: 

106 

107 .. doctest:: 

108 

109 >>> normalize_percent_triplet(("50%", "50%", "50%")) 

110 PercentRGB(red='50%', green='50%', blue='50%') 

111 >>> normalize_percent_triplet(("0%", "100%", "0%")) 

112 PercentRGB(red='0%', green='100%', blue='0%') 

113 >>> normalize_percent_triplet(("-10%", "-0%", "500%")) 

114 PercentRGB(red='0%', green='0%', blue='100%') 

115 

116 :param rgb_triplet: The percentage `rgb()` triplet to normalize. 

117 

118 """ 

119 return PercentRGB._make(_normalize_percent_rgb(value) for value in rgb_triplet) 

120 

121 

122def _percent_to_integer(percent: str) -> int: 

123 """ 

124 Internal helper for converting a percentage value to an integer between 0 and 

125 255 inclusive. 

126 

127 """ 

128 return int(round(float(percent.split("%")[0]) / 100 * 255))