diff --git a/Lib/colorsys.py b/Lib/colorsys.py index 9bdc83e3772603..44ff97e48554ea 100644 --- a/Lib/colorsys.py +++ b/Lib/colorsys.py @@ -78,7 +78,13 @@ def rgb_to_hls(r, g, b): sumc = (maxc+minc) rangec = (maxc-minc) l = sumc/2.0 - if minc == maxc: + # gh-106498 + # Due to a degree of float precision error, it's possible that maxc != minc + # but maxc + minc == 2.0. Which will make (2.0 - sumc) zero, causing the + # ZeroDivisionError. + # e.g. colorsys.rgb_to_hls(1, 1, 0.9999999999999999) + # In this case, it's an extreme near white color so we can just return white + if minc == maxc or sumc == 2.0: return 0.0, l, 0.0 if l <= 0.5: s = rangec / sumc diff --git a/Lib/test/test_colorsys.py b/Lib/test/test_colorsys.py index a24e3adcb4b842..1502394dfc9063 100644 --- a/Lib/test/test_colorsys.py +++ b/Lib/test/test_colorsys.py @@ -69,6 +69,12 @@ def test_hls_values(self): self.assertTripleEqual(hls, colorsys.rgb_to_hls(*rgb)) self.assertTripleEqual(rgb, colorsys.hls_to_rgb(*hls)) + def test_hls_corner_case(self): + try: + colorsys.rgb_to_hls(1, 1, 0.9999999999999999) + except Exception: + self.fail("rgb_to_hls(1, 1, 0.9999999999999999) raised an exception!") + def test_yiq_roundtrip(self): for r in frange(0.0, 1.0, 0.2): for g in frange(0.0, 1.0, 0.2): diff --git a/Misc/NEWS.d/next/Library/2023-07-07-19-46-27.gh-issue-106498.ijJ-eH.rst b/Misc/NEWS.d/next/Library/2023-07-07-19-46-27.gh-issue-106498.ijJ-eH.rst new file mode 100644 index 00000000000000..39d1a54c311ed1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-07-07-19-46-27.gh-issue-106498.ijJ-eH.rst @@ -0,0 +1 @@ +Fixed :func:`colorsys.rgb_to_hls` under an extreme input.