Skip to content

Commit a72f946

Browse files
committed
- make all internal classes and methods be prefixed using only a single underscore
- always put private methods at the very bottom inside classes - unnest the first few methods for `mypyc` compatibility
1 parent f266f43 commit a72f946

10 files changed

Lines changed: 680 additions & 589 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
* The library is now compiled using `mypyc` when installing, which makes it run significantly faster.
2525
* Unnest all the nested methods in the whole library for compatibility with `mypyc`.
2626
* Change the class-property definitions to be defined via `metaclass` and using `@property` decorators, to make them compatible with `mypyc`.
27+
* Changed the default syntax colors for `Data.to_str()` and therefore also `Data.print()` to console default colors.
28+
* Made internal, global constants, which's values never change, into `Final` constants for better type checking.
29+
* The names of all internal classes and methods are all noi longer prefixed with a double underscore (`__`), but a single underscore (`_`) instead.
30+
31+
**BREAKING CHANGES:**
32+
* Renamed `Data.to_str()` to `Data.render()`, since that describes its functionality better (*especially with the syntax highlighting option*).
33+
* Removed the `_` prefix from the param `_syntax_highlighting` in `Data.render()`, since it's no longer just for internal use.
2734

2835

2936
<span id="v1-9-2" />

src/xulbux/color.py

Lines changed: 79 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -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

525525
class 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

Comments
 (0)