Skip to content

Commit f9db7a3

Browse files
authored
Add has_feature_version helper (#9172)
2 parents 97a4d1f + f80ac8d commit f9db7a3

File tree

4 files changed

+57
-68
lines changed

4 files changed

+57
-68
lines changed

Tests/helper.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ def skip_unless_feature(feature: str) -> pytest.MarkDecorator:
175175
return pytest.mark.skipif(not features.check(feature), reason=reason)
176176

177177

178+
def has_feature_version(feature: str, required: str) -> bool:
179+
version = features.version(feature)
180+
assert version is not None
181+
version_required = parse_version(required)
182+
version_available = parse_version(version)
183+
return version_available >= version_required
184+
185+
178186
def skip_unless_feature_version(
179187
feature: str, required: str, reason: str | None = None
180188
) -> pytest.MarkDecorator:

Tests/test_file_webp_animated.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
from pathlib import Path
55

66
import pytest
7-
from packaging.version import parse as parse_version
87

9-
from PIL import GifImagePlugin, Image, WebPImagePlugin, features
8+
from PIL import GifImagePlugin, Image, WebPImagePlugin
109

1110
from .helper import (
1211
assert_image_equal,
1312
assert_image_similar,
13+
has_feature_version,
1414
is_big_endian,
1515
skip_unless_feature,
1616
)
@@ -53,11 +53,8 @@ def test_write_animation_L(tmp_path: Path) -> None:
5353
im.load()
5454
assert_image_similar(im, orig.convert("RGBA"), 32.9)
5555

56-
if is_big_endian():
57-
version = features.version_module("webp")
58-
assert version is not None
59-
if parse_version(version) < parse_version("1.2.2"):
60-
pytest.skip("Fails with libwebp earlier than 1.2.2")
56+
if is_big_endian() and not has_feature_version("webp", "1.2.2"):
57+
pytest.skip("Fails with libwebp earlier than 1.2.2")
6158
orig.seek(orig.n_frames - 1)
6259
im.seek(im.n_frames - 1)
6360
orig.load()
@@ -81,11 +78,8 @@ def check(temp_file: Path) -> None:
8178
assert_image_equal(im, frame1.convert("RGBA"))
8279

8380
# Compare second frame to original
84-
if is_big_endian():
85-
version = features.version_module("webp")
86-
assert version is not None
87-
if parse_version(version) < parse_version("1.2.2"):
88-
pytest.skip("Fails with libwebp earlier than 1.2.2")
81+
if is_big_endian() and not has_feature_version("webp", "1.2.2"):
82+
pytest.skip("Fails with libwebp earlier than 1.2.2")
8983
im.seek(1)
9084
im.load()
9185
assert_image_equal(im, frame2.convert("RGBA"))

Tests/test_image_quantize.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
from __future__ import annotations
22

33
import pytest
4-
from packaging.version import parse as parse_version
54

6-
from PIL import Image, features
5+
from PIL import Image
76

8-
from .helper import assert_image_similar, hopper, is_ppc64le, skip_unless_feature
7+
from .helper import (
8+
assert_image_similar,
9+
has_feature_version,
10+
hopper,
11+
is_ppc64le,
12+
skip_unless_feature,
13+
)
914

1015

1116
def test_sanity() -> None:
@@ -23,11 +28,8 @@ def test_sanity() -> None:
2328
@skip_unless_feature("libimagequant")
2429
def test_libimagequant_quantize() -> None:
2530
image = hopper()
26-
if is_ppc64le():
27-
version = features.version_feature("libimagequant")
28-
assert version is not None
29-
if parse_version(version) < parse_version("4"):
30-
pytest.skip("Fails with libimagequant earlier than 4.0.0 on ppc64le")
31+
if is_ppc64le() and not has_feature_version("libimagequant", "4"):
32+
pytest.skip("Fails with libimagequant earlier than 4.0.0 on ppc64le")
3133
converted = image.quantize(100, Image.Quantize.LIBIMAGEQUANT)
3234
assert converted.mode == "P"
3335
assert_image_similar(converted.convert("RGB"), image, 15)

Tests/test_imagefontctl.py

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from .helper import (
88
assert_image_equal_tofile,
99
assert_image_similar_tofile,
10+
has_feature_version,
1011
skip_unless_feature,
1112
)
1213

@@ -104,11 +105,9 @@ def test_text_direction_ttb() -> None:
104105

105106
im = Image.new(mode="RGB", size=(100, 300))
106107
draw = ImageDraw.Draw(im)
107-
try:
108-
draw.text((0, 0), "English あい", font=ttf, fill=500, direction="ttb")
109-
except ValueError as ex:
110-
if str(ex) == "libraqm 0.7 or greater required for 'ttb' direction":
111-
pytest.skip("libraqm 0.7 or greater not available")
108+
if not has_feature_version("raqm", "0.7"):
109+
pytest.skip("libraqm 0.7 or greater not available")
110+
draw.text((0, 0), "English あい", font=ttf, fill=500, direction="ttb")
112111

113112
target = "Tests/images/test_direction_ttb.png"
114113
assert_image_similar_tofile(im, target, 2.8)
@@ -119,19 +118,17 @@ def test_text_direction_ttb_stroke() -> None:
119118

120119
im = Image.new(mode="RGB", size=(100, 300))
121120
draw = ImageDraw.Draw(im)
122-
try:
123-
draw.text(
124-
(27, 27),
125-
"あい",
126-
font=ttf,
127-
fill=500,
128-
direction="ttb",
129-
stroke_width=2,
130-
stroke_fill="#0f0",
131-
)
132-
except ValueError as ex:
133-
if str(ex) == "libraqm 0.7 or greater required for 'ttb' direction":
134-
pytest.skip("libraqm 0.7 or greater not available")
121+
if not has_feature_version("raqm", "0.7"):
122+
pytest.skip("libraqm 0.7 or greater not available")
123+
draw.text(
124+
(27, 27),
125+
"あい",
126+
font=ttf,
127+
fill=500,
128+
direction="ttb",
129+
stroke_width=2,
130+
stroke_fill="#0f0",
131+
)
135132

136133
target = "Tests/images/test_direction_ttb_stroke.png"
137134
assert_image_similar_tofile(im, target, 19.4)
@@ -219,14 +216,9 @@ def test_getlength(
219216
im = Image.new(mode, (1, 1), 0)
220217
d = ImageDraw.Draw(im)
221218

222-
try:
223-
assert d.textlength(text, ttf, direction) == expected
224-
except ValueError as ex:
225-
if (
226-
direction == "ttb"
227-
and str(ex) == "libraqm 0.7 or greater required for 'ttb' direction"
228-
):
229-
pytest.skip("libraqm 0.7 or greater not available")
219+
if direction == "ttb" and not has_feature_version("raqm", "0.7"):
220+
pytest.skip("libraqm 0.7 or greater not available")
221+
assert d.textlength(text, ttf, direction) == expected
230222

231223

232224
@pytest.mark.parametrize("mode", ("L", "1"))
@@ -242,17 +234,12 @@ def test_getlength_combine(mode: str, direction: str, text: str) -> None:
242234

243235
ttf = ImageFont.truetype("Tests/fonts/NotoSans-Regular.ttf", 48)
244236

245-
try:
246-
target = ttf.getlength("ii", mode, direction)
247-
actual = ttf.getlength(text, mode, direction)
237+
if direction == "ttb" and not has_feature_version("raqm", "0.7"):
238+
pytest.skip("libraqm 0.7 or greater not available")
239+
target = ttf.getlength("ii", mode, direction)
240+
actual = ttf.getlength(text, mode, direction)
248241

249-
assert actual == target
250-
except ValueError as ex:
251-
if (
252-
direction == "ttb"
253-
and str(ex) == "libraqm 0.7 or greater required for 'ttb' direction"
254-
):
255-
pytest.skip("libraqm 0.7 or greater not available")
242+
assert actual == target
256243

257244

258245
@pytest.mark.parametrize("anchor", ("lt", "mm", "rb", "sm"))
@@ -265,11 +252,9 @@ def test_anchor_ttb(anchor: str) -> None:
265252
d = ImageDraw.Draw(im)
266253
d.line(((0, 200), (200, 200)), "gray")
267254
d.line(((100, 0), (100, 400)), "gray")
268-
try:
269-
d.text((100, 200), text, fill="black", anchor=anchor, direction="ttb", font=f)
270-
except ValueError as ex:
271-
if str(ex) == "libraqm 0.7 or greater required for 'ttb' direction":
272-
pytest.skip("libraqm 0.7 or greater not available")
255+
if not has_feature_version("raqm", "0.7"):
256+
pytest.skip("libraqm 0.7 or greater not available")
257+
d.text((100, 200), text, fill="black", anchor=anchor, direction="ttb", font=f)
273258

274259
assert_image_similar_tofile(im, path, 1) # fails at 5
275260

@@ -310,10 +295,12 @@ def test_anchor_ttb(anchor: str) -> None:
310295

311296
# this tests various combining characters for anchor alignment and clipping
312297
@pytest.mark.parametrize(
313-
"name, text, anchor, dir, epsilon", combine_tests, ids=[r[0] for r in combine_tests]
298+
"name, text, anchor, direction, epsilon",
299+
combine_tests,
300+
ids=[r[0] for r in combine_tests],
314301
)
315302
def test_combine(
316-
name: str, text: str, dir: str | None, anchor: str | None, epsilon: float
303+
name: str, text: str, direction: str | None, anchor: str | None, epsilon: float
317304
) -> None:
318305
path = f"Tests/images/test_combine_{name}.png"
319306
f = ImageFont.truetype("Tests/fonts/NotoSans-Regular.ttf", 48)
@@ -322,11 +309,9 @@ def test_combine(
322309
d = ImageDraw.Draw(im)
323310
d.line(((0, 200), (400, 200)), "gray")
324311
d.line(((200, 0), (200, 400)), "gray")
325-
try:
326-
d.text((200, 200), text, fill="black", anchor=anchor, direction=dir, font=f)
327-
except ValueError as ex:
328-
if str(ex) == "libraqm 0.7 or greater required for 'ttb' direction":
329-
pytest.skip("libraqm 0.7 or greater not available")
312+
if direction == "ttb" and not has_feature_version("raqm", "0.7"):
313+
pytest.skip("libraqm 0.7 or greater not available")
314+
d.text((200, 200), text, fill="black", anchor=anchor, direction=direction, font=f)
330315

331316
assert_image_similar_tofile(im, path, epsilon)
332317

0 commit comments

Comments
 (0)