@@ -96,7 +96,7 @@ def values(self) -> tuple:
9696
9797 def to_hsla (self ) -> "hsla" :
9898 """Returns the color as `hsla()` color object."""
99- h , s , l = self .__rgb_to_hsl (self .r , self .g , self .b )
99+ h , s , l = self ._rgb_to_hsl (self .r , self .g , self .b )
100100 return hsla (h , s , l , self .a , _validate = False )
101101
102102 def to_hexa (self ) -> "hexa" :
@@ -249,7 +249,7 @@ def complementary(self) -> "rgba":
249249 return self .to_hsla ().complementary ().to_rgba ()
250250
251251 @staticmethod
252- def __rgb_to_hsl (r : int , g : int , b : int ) -> tuple :
252+ def _rgb_to_hsl (r : int , g : int , b : int ) -> tuple :
253253 """Internal method to convert RGB to HSL color space."""
254254 _r , _g , _b = r / 255.0 , g / 255.0 , b / 255.0
255255 max_c , min_c = max (_r , _g , _b ), min (_r , _g , _b )
@@ -355,12 +355,12 @@ def values(self) -> tuple:
355355
356356 def to_rgba (self ) -> "rgba" :
357357 """Returns the color as `rgba()` color object."""
358- r , g , b = self .__hsl_to_rgb (self .h , self .s , self .l )
358+ r , g , b = self ._hsl_to_rgb (self .h , self .s , self .l )
359359 return rgba (r , g , b , self .a , _validate = False )
360360
361361 def to_hexa (self ) -> "hexa" :
362362 """Returns the color as `hexa()` color object."""
363- r , g , b = self .__hsl_to_rgb (self .h , self .s , self .l )
363+ r , g , b = self ._hsl_to_rgb (self .h , self .s , self .l )
364364 return hexa ("" , r , g , b , self .a )
365365
366366 def has_alpha (self ) -> bool :
@@ -436,7 +436,7 @@ def grayscale(self, method: Literal["wcag2", "wcag3", "simple", "bt601"] = "wcag
436436 * `"simple"` Simple arithmetic mean (less accurate)
437437 * `"bt601"` ITU-R BT.601 standard (older TV standard)"""
438438 # THE 'method' PARAM IS CHECKED IN 'Color.luminance()'
439- r , g , b = self .__hsl_to_rgb (self .h , self .s , self .l )
439+ r , g , b = self ._hsl_to_rgb (self .h , self .s , self .l )
440440 l = int (Color .luminance (r , g , b , output_type = None , method = method ))
441441 self .h , self .s , self .l , _ = rgba (l , l , l , _validate = False ).to_hsla ().values ()
442442 return hsla (self .h , self .s , self .l , self .a , _validate = False )
@@ -491,8 +491,24 @@ def complementary(self) -> "hsla":
491491 """Returns the complementary color (180 degrees on the color wheel)."""
492492 return hsla ((self .h + 180 ) % 360 , self .s , self .l , self .a , _validate = False )
493493
494+ @classmethod
495+ def _hsl_to_rgb (cls , h : int , s : int , l : int ) -> tuple :
496+ """Internal method to convert HSL to RGB color space."""
497+ _h , _s , _l = h / 360 , s / 100 , l / 100
498+
499+ if _s == 0 :
500+ r = g = b = int (_l * 255 )
501+ else :
502+ q = _l * (1 + _s ) if _l < 0.5 else _l + _s - _l * _s
503+ p = 2 * _l - q
504+ r = int (round (cls ._hue_to_rgb (p , q , _h + 1 / 3 ) * 255 ))
505+ g = int (round (cls ._hue_to_rgb (p , q , _h ) * 255 ))
506+ b = int (round (cls ._hue_to_rgb (p , q , _h - 1 / 3 ) * 255 ))
507+
508+ return r , g , b
509+
494510 @staticmethod
495- def __hue_to_rgb (p : float , q : float , t : float ) -> float :
511+ def _hue_to_rgb (p : float , q : float , t : float ) -> float :
496512 if t < 0 :
497513 t += 1
498514 if t > 1 :
@@ -505,22 +521,6 @@ def __hue_to_rgb(p: float, q: float, t: float) -> float:
505521 return p + (q - p ) * (2 / 3 - t ) * 6
506522 return p
507523
508- @classmethod
509- def __hsl_to_rgb (cls , h : int , s : int , l : int ) -> tuple :
510- """Internal method to convert HSL to RGB color space."""
511- _h , _s , _l = h / 360 , s / 100 , l / 100
512-
513- if _s == 0 :
514- r = g = b = int (_l * 255 )
515- else :
516- q = _l * (1 + _s ) if _l < 0.5 else _l + _s - _l * _s
517- p = 2 * _l - q
518- r = int (round (cls .__hue_to_rgb (p , q , _h + 1 / 3 ) * 255 ))
519- g = int (round (cls .__hue_to_rgb (p , q , _h ) * 255 ))
520- b = int (round (cls .__hue_to_rgb (p , q , _h - 1 / 3 ) * 255 ))
521-
522- return r , g , b
523-
524524
525525class hexa :
526526 """A HEXA color object that includes a bunch of methods to manipulate the color.\n
@@ -933,40 +933,6 @@ def is_valid(cls, color: AnyRgba | AnyHsla | AnyHexa, allow_alpha: bool = True)
933933 or cls .is_valid_hexa (color , allow_alpha )
934934 )
935935
936- @classmethod
937- def __parse_rgba (cls , color : AnyRgba ) -> rgba :
938- """Internal method to parse a color to an RGBA object."""
939- if isinstance (color , rgba ):
940- return color
941- elif isinstance (color , (list , tuple )):
942- if len (color ) == 4 :
943- return rgba (color [0 ], color [1 ], color [2 ], color [3 ], _validate = False )
944- elif len (color ) == 3 :
945- return rgba (color [0 ], color [1 ], color [2 ], None , _validate = False )
946- elif isinstance (color , dict ):
947- return rgba (color ["r" ], color ["g" ], color ["b" ], color .get ("a" ), _validate = False )
948- elif isinstance (color , str ):
949- if parsed := cls .str_to_rgba (color , only_first = True ):
950- return cast (rgba , parsed )
951- raise ValueError (f"Could not parse RGBA color: { color !r} " )
952-
953- @classmethod
954- def __parse_hsla (cls , color : AnyHsla ) -> hsla :
955- """Internal method to parse a color to an HSLA object."""
956- if isinstance (color , hsla ):
957- return color
958- elif isinstance (color , (list , tuple )):
959- if len (color ) == 4 :
960- return hsla (color [0 ], color [1 ], color [2 ], color [3 ], _validate = False )
961- elif len (color ) == 3 :
962- return hsla (color [0 ], color [1 ], color [2 ], None , _validate = False )
963- elif isinstance (color , dict ):
964- return hsla (color ["h" ], color ["s" ], color ["l" ], color .get ("a" ), _validate = False )
965- elif isinstance (color , str ):
966- if parsed := cls .str_to_hsla (color , only_first = True ):
967- return cast (hsla , parsed )
968- raise ValueError (f"Could not parse HSLA color: { color !r} " )
969-
970936 @classmethod
971937 def has_alpha (cls , color : Rgba | Hsla | Hexa ) -> bool :
972938 """Check if the given color has an alpha channel.\n
@@ -1007,11 +973,11 @@ def to_rgba(cls, color: Rgba | Hsla | Hexa) -> rgba:
1007973 if isinstance (color , (hsla , hexa )):
1008974 return color .to_rgba ()
1009975 elif cls .is_valid_hsla (color ):
1010- return cls .__parse_hsla (color ).to_rgba ()
976+ return cls ._parse_hsla (color ).to_rgba ()
1011977 elif cls .is_valid_hexa (color ):
1012978 return hexa (cast (str | int , color )).to_rgba ()
1013979 elif cls .is_valid_rgba (color ):
1014- return cls .__parse_rgba (color )
980+ return cls ._parse_rgba (color )
1015981 raise ValueError (f"Could not convert color { color !r} to RGBA." )
1016982
1017983 @classmethod
@@ -1022,11 +988,11 @@ def to_hsla(cls, color: Rgba | Hsla | Hexa) -> hsla:
1022988 if isinstance (color , (rgba , hexa )):
1023989 return color .to_hsla ()
1024990 elif cls .is_valid_rgba (color ):
1025- return cls .__parse_rgba (color ).to_hsla ()
991+ return cls ._parse_rgba (color ).to_hsla ()
1026992 elif cls .is_valid_hexa (color ):
1027993 return hexa (cast (str | int , color )).to_hsla ()
1028994 elif cls .is_valid_hsla (color ):
1029- return cls .__parse_hsla (color )
995+ return cls ._parse_hsla (color )
1030996 raise ValueError (f"Could not convert color { color !r} to HSLA." )
1031997
1032998 @classmethod
@@ -1037,9 +1003,9 @@ def to_hexa(cls, color: Rgba | Hsla | Hexa) -> hexa:
10371003 if isinstance (color , (rgba , hsla )):
10381004 return color .to_hexa ()
10391005 elif cls .is_valid_rgba (color ):
1040- return cls .__parse_rgba (color ).to_hexa ()
1006+ return cls ._parse_rgba (color ).to_hexa ()
10411007 elif cls .is_valid_hsla (color ):
1042- return cls .__parse_hsla (color ).to_hexa ()
1008+ return cls ._parse_hsla (color ).to_hexa ()
10431009 elif cls .is_valid_hexa (color ):
10441010 return color if isinstance (color , hexa ) else hexa (cast (str | int , color ))
10451011 raise ValueError (f"Could not convert color { color !r} to HEXA" )
@@ -1183,17 +1149,6 @@ def hex_int_to_rgba(cls, hex_int: int, preserve_original: bool = False) -> rgba:
11831149 else :
11841150 raise ValueError (f"Could not convert HEX integer 0x{ hex_int :X} to RGBA color." )
11851151
1186- @staticmethod
1187- def __linearize_srgb (c : float ) -> float :
1188- """Helper method to linearize sRGB component following the WCAG standard."""
1189- if not (0.0 <= c <= 1.0 ):
1190- raise ValueError (f"The 'c' parameter must be in range [0.0, 1.0] inclusive, got { c !r} " )
1191-
1192- if c <= 0.03928 :
1193- return c / 12.92
1194- else :
1195- return ((c + 0.055 ) / 1.055 )** 2.4
1196-
11971152 @classmethod
11981153 def luminance (
11991154 cls ,
@@ -1227,14 +1182,14 @@ def luminance(
12271182 elif method == "bt601" :
12281183 luminance = 0.299 * _r + 0.587 * _g + 0.114 * _b
12291184 elif method == "wcag3" :
1230- _r = cls .__linearize_srgb (_r )
1231- _g = cls .__linearize_srgb (_g )
1232- _b = cls .__linearize_srgb (_b )
1185+ _r = cls ._linearize_srgb (_r )
1186+ _g = cls ._linearize_srgb (_g )
1187+ _b = cls ._linearize_srgb (_b )
12331188 luminance = 0.2126729 * _r + 0.7151522 * _g + 0.0721750 * _b
12341189 else :
1235- _r = cls .__linearize_srgb (_r )
1236- _g = cls .__linearize_srgb (_g )
1237- _b = cls .__linearize_srgb (_b )
1190+ _r = cls ._linearize_srgb (_r )
1191+ _g = cls ._linearize_srgb (_g )
1192+ _b = cls ._linearize_srgb (_b )
12381193 luminance = 0.2126 * _r + 0.7152 * _g + 0.0722 * _b
12391194
12401195 if output_type == int :
@@ -1315,3 +1270,48 @@ def adjust_saturation(cls, color: Rgba | Hexa, saturation_change: float) -> rgba
13151270 hsla (h , s , l , a , _validate = False ).to_hexa () if was_hexa \
13161271 else hsla (h , s , l , a , _validate = False ).to_rgba ()
13171272 )
1273+
1274+ @classmethod
1275+ def _parse_rgba (cls , color : AnyRgba ) -> rgba :
1276+ """Internal method to parse a color to an RGBA object."""
1277+ if isinstance (color , rgba ):
1278+ return color
1279+ elif isinstance (color , (list , tuple )):
1280+ if len (color ) == 4 :
1281+ return rgba (color [0 ], color [1 ], color [2 ], color [3 ], _validate = False )
1282+ elif len (color ) == 3 :
1283+ return rgba (color [0 ], color [1 ], color [2 ], None , _validate = False )
1284+ elif isinstance (color , dict ):
1285+ return rgba (color ["r" ], color ["g" ], color ["b" ], color .get ("a" ), _validate = False )
1286+ elif isinstance (color , str ):
1287+ if parsed := cls .str_to_rgba (color , only_first = True ):
1288+ return cast (rgba , parsed )
1289+ raise ValueError (f"Could not parse RGBA color: { color !r} " )
1290+
1291+ @classmethod
1292+ def _parse_hsla (cls , color : AnyHsla ) -> hsla :
1293+ """Internal method to parse a color to an HSLA object."""
1294+ if isinstance (color , hsla ):
1295+ return color
1296+ elif isinstance (color , (list , tuple )):
1297+ if len (color ) == 4 :
1298+ return hsla (color [0 ], color [1 ], color [2 ], color [3 ], _validate = False )
1299+ elif len (color ) == 3 :
1300+ return hsla (color [0 ], color [1 ], color [2 ], None , _validate = False )
1301+ elif isinstance (color , dict ):
1302+ return hsla (color ["h" ], color ["s" ], color ["l" ], color .get ("a" ), _validate = False )
1303+ elif isinstance (color , str ):
1304+ if parsed := cls .str_to_hsla (color , only_first = True ):
1305+ return cast (hsla , parsed )
1306+ raise ValueError (f"Could not parse HSLA color: { color !r} " )
1307+
1308+ @staticmethod
1309+ def _linearize_srgb (c : float ) -> float :
1310+ """Helper method to linearize sRGB component following the WCAG standard."""
1311+ if not (0.0 <= c <= 1.0 ):
1312+ raise ValueError (f"The 'c' parameter must be in range [0.0, 1.0] inclusive, got { c !r} " )
1313+
1314+ if c <= 0.03928 :
1315+ return c / 12.92
1316+ else :
1317+ return ((c + 0.055 ) / 1.055 )** 2.4
0 commit comments