From 89c771428ad378ea35f62f0811f9d118991085cf Mon Sep 17 00:00:00 2001 From: Shriya Date: Tue, 7 Oct 2025 14:41:37 -0700 Subject: [PATCH 1/2] fix: add validation for RGB/BGR color values in Color class - Add range validation (0-255) to from_rgb_tuple() and from_bgr_tuple() - Raise ValueError for invalid color values with descriptive messages - Add comprehensive tests for both valid and invalid cases - Update docstrings to document the new validation behavior --- supervision/draw/color.py | 14 ++++++++++++ test/draw/test_color.py | 46 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/supervision/draw/color.py b/supervision/draw/color.py index 705d5922c..cdcd90bc0 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,10 @@ 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 +172,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 +184,10 @@ 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..fda0f804f 100644 --- a/test/draw/test_color.py +++ b/test/draw/test_color.py @@ -50,3 +50,49 @@ 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 From fd2e5518765936ba9902fdb0f89a0e0f7364a1cf Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 21:48:13 +0000 Subject: [PATCH 2/2] =?UTF-8?q?fix(pre=5Fcommit):=20=F0=9F=8E=A8=20auto=20?= =?UTF-8?q?format=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supervision/draw/color.py | 8 ++------ test/draw/test_color.py | 8 ++++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/supervision/draw/color.py b/supervision/draw/color.py index cdcd90bc0..6cc72018f 100644 --- a/supervision/draw/color.py +++ b/supervision/draw/color.py @@ -155,9 +155,7 @@ 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})" - ) + raise ValueError(f"RGB values must be in range 0-255, got ({r}, {g}, {b})") return cls(r=r, g=g, b=b) @classmethod @@ -185,9 +183,7 @@ 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})" - ) + 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 fda0f804f..55b624adc 100644 --- a/test/draw/test_color.py +++ b/test/draw/test_color.py @@ -68,7 +68,9 @@ def test_color_as_hex( ], ) def test_color_from_rgb_tuple( - color_tuple: tuple[int, int, int], expected_result: Color | None, exception: Exception + color_tuple: tuple[int, int, int], + expected_result: Color | None, + exception: Exception, ) -> None: with exception: result = Color.from_rgb_tuple(color_tuple=color_tuple) @@ -91,7 +93,9 @@ def test_color_from_rgb_tuple( ], ) def test_color_from_bgr_tuple( - color_tuple: tuple[int, int, int], expected_result: Color | None, exception: Exception + color_tuple: tuple[int, int, int], + expected_result: Color | None, + exception: Exception, ) -> None: with exception: result = Color.from_bgr_tuple(color_tuple=color_tuple)