From 7e91108c525c6e9626f49638b73557c3ad4ea3f3 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 29 Jul 2026 18:43:09 +0300 Subject: [PATCH 1/2] Add xfailing test for pa2p quirk --- Tests/test_image_convert.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Tests/test_image_convert.py b/Tests/test_image_convert.py index 547a6c2c678..de0131edbb2 100644 --- a/Tests/test_image_convert.py +++ b/Tests/test_image_convert.py @@ -290,6 +290,19 @@ def test_p2pa_palette() -> None: assert im_pa.getpalette() == im.getpalette() +@pytest.mark.xfail(reason="zombie colors from palette shouldn't reappear") +def test_pa2p_truly_drops_alpha() -> None: + im = Image.frombytes("P", (2, 1), bytes([0, 1])).convert("PA") + im.putpalette(bytes([255, 0, 0, 7, 0, 255, 0, 9]), "RGBA") + im.putalpha(Image.frombytes("L", (2, 1), bytes([240, 220]))) + assert im.get_flattened_data() == ((0, 240), (1, 220)) # Matches the alpha band + im_p = im.convert("P") + assert im_p.palette is not None + assert im_p.im.getpalettemode() == im_p.palette.mode == "RGB" + rgba_data = im_p.convert("RGBA").get_flattened_data() + assert rgba_data == ((255, 0, 0, 255), (0, 255, 0, 255)) + + def test_matrix_illegal_conversion() -> None: # Arrange im = hopper("CMYK") From 215cece7c84aba2c066969f08e2a97120c2e107b Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Wed, 29 Jul 2026 18:44:24 +0300 Subject: [PATCH 2/2] Ensure Image and core palettes are in sync after PA conversion (alphas dropped) Co-authored-by: Andrew Murray --- Tests/test_image_convert.py | 1 - src/PIL/Image.py | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Tests/test_image_convert.py b/Tests/test_image_convert.py index de0131edbb2..fdb96c5e4fb 100644 --- a/Tests/test_image_convert.py +++ b/Tests/test_image_convert.py @@ -290,7 +290,6 @@ def test_p2pa_palette() -> None: assert im_pa.getpalette() == im.getpalette() -@pytest.mark.xfail(reason="zombie colors from palette shouldn't reappear") def test_pa2p_truly_drops_alpha() -> None: im = Image.frombytes("P", (2, 1), bytes([0, 1])).convert("PA") im.putpalette(bytes([255, 0, 0, 7, 0, 255, 0, 9]), "RGBA") diff --git a/src/PIL/Image.py b/src/PIL/Image.py index ddbaec20a05..1c1f5af0f01 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1242,9 +1242,8 @@ def convert_transparency( new_im = self._new(im) if mode in ("P", "PA") and palette != Palette.ADAPTIVE: - from . import ImagePalette - - new_im.palette = ImagePalette.ImagePalette("RGB", im.getpalette("RGB")) + # Install the original image's palette into the new copy + new_im.putpalette(im.getpalette("RGB")) if delete_trns: # crash fail if we leave a bytes transparency in an rgb/l mode. del new_im.info["transparency"]