diff --git a/supervision/draw/color.py b/supervision/draw/color.py index 705d5922c..6cc72018f 100644 --- a/supervision/draw/color.py +++ b/supervision/draw/color.py @@ -142,6 +142,9 @@ def from_rgb_tuple(cls, color_tuple: tuple[int, int, int]) -> Color: Returns: Color: An instance representing the color. + Raises: + ValueError: If any RGB value is outside the range 0-255. + Example: ```python import supervision as sv @@ -151,6 +154,8 @@ def from_rgb_tuple(cls, color_tuple: tuple[int, int, int]) -> Color: ``` """ r, g, b = color_tuple + if not (0 <= r <= 255 and 0 <= g <= 255 and 0 <= b <= 255): + raise ValueError(f"RGB values must be in range 0-255, got ({r}, {g}, {b})") return cls(r=r, g=g, b=b) @classmethod @@ -165,6 +170,9 @@ def from_bgr_tuple(cls, color_tuple: tuple[int, int, int]) -> Color: Returns: Color: An instance representing the color. + Raises: + ValueError: If any BGR value is outside the range 0-255. + Example: ```python import supervision as sv @@ -174,6 +182,8 @@ def from_bgr_tuple(cls, color_tuple: tuple[int, int, int]) -> Color: ``` """ b, g, r = color_tuple + if not (0 <= r <= 255 and 0 <= g <= 255 and 0 <= b <= 255): + raise ValueError(f"BGR values must be in range 0-255, got ({b}, {g}, {r})") return cls(r=r, g=g, b=b) def as_hex(self) -> str: diff --git a/test/draw/test_color.py b/test/draw/test_color.py index 05ad68627..55b624adc 100644 --- a/test/draw/test_color.py +++ b/test/draw/test_color.py @@ -50,3 +50,53 @@ def test_color_as_hex( with exception: result = color.as_hex() assert result == expected_result + + +@pytest.mark.parametrize( + "color_tuple, expected_result, exception", + [ + ((255, 255, 255), Color.WHITE, DoesNotRaise()), + ((0, 0, 0), Color.BLACK, DoesNotRaise()), + ((255, 0, 0), Color.RED, DoesNotRaise()), + ((0, 255, 0), Color.GREEN, DoesNotRaise()), + ((0, 0, 255), Color.BLUE, DoesNotRaise()), + ((128, 128, 0), Color(r=128, g=128, b=0), DoesNotRaise()), + ((300, 0, 0), None, pytest.raises(ValueError)), # R out of range + ((0, -10, 0), None, pytest.raises(ValueError)), # G out of range + ((0, 0, 500), None, pytest.raises(ValueError)), # B out of range + ((300, -10, 500), None, pytest.raises(ValueError)), # All out of range + ], +) +def test_color_from_rgb_tuple( + color_tuple: tuple[int, int, int], + expected_result: Color | None, + exception: Exception, +) -> None: + with exception: + result = Color.from_rgb_tuple(color_tuple=color_tuple) + assert result == expected_result + + +@pytest.mark.parametrize( + "color_tuple, expected_result, exception", + [ + ((255, 255, 255), Color.WHITE, DoesNotRaise()), + ((0, 0, 0), Color.BLACK, DoesNotRaise()), + ((0, 0, 255), Color.RED, DoesNotRaise()), # BGR format + ((0, 255, 0), Color.GREEN, DoesNotRaise()), # BGR format + ((255, 0, 0), Color.BLUE, DoesNotRaise()), # BGR format + ((0, 128, 128), Color(r=128, g=128, b=0), DoesNotRaise()), # BGR format + ((300, 0, 0), None, pytest.raises(ValueError)), # B out of range + ((0, -10, 0), None, pytest.raises(ValueError)), # G out of range + ((0, 0, 500), None, pytest.raises(ValueError)), # R out of range + ((300, -10, 500), None, pytest.raises(ValueError)), # All out of range + ], +) +def test_color_from_bgr_tuple( + color_tuple: tuple[int, int, int], + expected_result: Color | None, + exception: Exception, +) -> None: + with exception: + result = Color.from_bgr_tuple(color_tuple=color_tuple) + assert result == expected_result