From 76d6228fed2c47d975e61cfe6e9c6c7e8e6fdef4 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 3 Jan 2026 11:30:20 +1100 Subject: [PATCH 1/2] Allow duplicate variation names --- src/PIL/ImageFont.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index d11f7bf01ad..2e8ace98dda 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -675,12 +675,8 @@ def get_variation_names(self) -> list[bytes]: :returns: A list of the named styles in a variation font. :exception OSError: If the font is not a variation font. """ - names = [] - for name in self.font.getvarnames(): - name = name.replace(b"\x00", b"") - if name not in names: - names.append(name) - return names + names = self.font.getvarnames() + return [name.replace(b"\x00", b"") for name in names] def set_variation_by_name(self, name: str | bytes) -> None: """ From 4cf281b8495481751cbf05ee13202cc03df7cc8e Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 3 Jan 2026 11:46:55 +1100 Subject: [PATCH 2/2] Added set_variation_by_name_index --- Tests/test_imagefont.py | 14 ++++++++++++++ src/PIL/ImageFont.py | 9 ++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index d0b458d6b77..9643d705fbd 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -753,6 +753,8 @@ def test_variation_duplicates() -> None: b"Black", b"Black Medium Contrast", b"Black High Contrast", + b"Black High Contrast", + b"Black High Contrast", b"Default", ] @@ -791,6 +793,18 @@ def test_variation_set_by_name(font: ImageFont.FreeTypeFont) -> None: _check_text(font, "Tests/images/variation_tiny_name.png", 40) +def test_variation_set_by_name_index(font: ImageFont.FreeTypeFont) -> None: + with pytest.raises(OSError): + font.set_variation_by_name_index(0) + + font = ImageFont.truetype("Tests/fonts/AdobeVFPrototype.ttf", 36) + _check_text(font, "Tests/images/variation_adobe.png", 11) + index = font.get_variation_names().index(b"Bold") + font.set_variation_by_name_index(index) + assert font.getname()[1] == "Bold" + _check_text(font, "Tests/images/variation_adobe_name.png", 16) + + def test_variation_set_by_axes(font: ImageFont.FreeTypeFont) -> None: with pytest.raises(OSError): font.set_variation_by_axes([500, 50]) diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index 2e8ace98dda..602b3f4c3de 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -686,7 +686,14 @@ def set_variation_by_name(self, name: str | bytes) -> None: names = self.get_variation_names() if not isinstance(name, bytes): name = name.encode() - index = names.index(name) + 1 + self.set_variation_by_name_index(names.index(name)) + + def set_variation_by_name_index(self, index: int) -> None: + """ + :param name: The index within the list of named styles in a variation font. + :exception OSError: If the font is not a variation font. + """ + index += 1 if index == getattr(self, "_last_variation_index", None): # When the same name is set twice in a row,