From 89bb1cc2927733a6d21857da1440906b6cb953ff Mon Sep 17 00:00:00 2001 From: Pranjal Date: Tue, 11 Aug 2026 19:02:29 +0530 Subject: [PATCH] Add tests for remap_palette()'s explicit source_palette argument The existing remap_palette tests only cover the source_palette=None path, so the length-based palette-mode detection for an explicitly passed source_palette had no coverage at all -- including at the 768-byte boundary between a full 256-entry RGB palette and an RGBA one. Covers both sides of that boundary, pinning the current (correct) behaviour: 768 bytes stays RGB, 1024 bytes is detected as RGBA. --- Tests/test_image.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Tests/test_image.py b/Tests/test_image.py index 413631bd8f0..40b129192f0 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -674,6 +674,29 @@ def test_remap_palette(self) -> None: with pytest.raises(ValueError): im_hopper.remap_palette([]) + @pytest.mark.parametrize( + "bands, palette_mode", ((3, "RGB"), (4, "RGBA")), ids=("RGB", "RGBA") + ) + def test_remap_palette_source_palette(self, bands: int, palette_mode: str) -> None: + # When source_palette is passed explicitly its mode is inferred from its + # length, so a full 256-entry RGB palette (exactly 768 bytes) must stay + # RGB while a 256-entry RGBA one (1024 bytes) is detected as RGBA. + source_palette = bytes( + (entry + channel * 17) % 256 + for entry in range(256) + for channel in range(bands) + ) + assert len(source_palette) == 256 * bands + + im = Image.new("P", (256, 1)) + for x in range(256): + im.putpixel((x, 0), x) + + im_remapped = im.remap_palette(list(range(256)), source_palette) + assert im_remapped.palette is not None + assert im_remapped.palette.mode == palette_mode + assert im_remapped.palette.palette == source_palette + def test_remap_palette_transparency(self) -> None: im = Image.new("P", (1, 2), (0, 0, 0)) im.putpixel((0, 1), (255, 0, 0))