From 8ea91dd54a48a698cb18eb6148d4570b0e3ac2a5 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 27 Aug 2026 18:47:50 +0300 Subject: [PATCH 1/3] Don't use `subprocess` to find test images and fonts Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- Tests/oss-fuzz/test_fuzzers.py | 37 +++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/Tests/oss-fuzz/test_fuzzers.py b/Tests/oss-fuzz/test_fuzzers.py index 37d11e0ba4c..cb5274f5a14 100644 --- a/Tests/oss-fuzz/test_fuzzers.py +++ b/Tests/oss-fuzz/test_fuzzers.py @@ -1,6 +1,6 @@ from __future__ import annotations -import subprocess +import pathlib import sys import fuzzers @@ -21,17 +21,23 @@ reason="Known failing with libjpeg_turbo 2.0" ) +tests_path = pathlib.Path(__file__).parent.parent + + +def find_files(subdir: str) -> list[pathlib.Path]: + return [path for path in tests_path.joinpath(subdir).rglob("*") if path.is_file()] + @pytest.mark.parametrize( "path", - subprocess.check_output("find Tests/images -type f", shell=True).split(b"\n"), + find_files("images"), + ids=lambda p: str(p.relative_to(tests_path)), ) -def test_fuzz_images(path: str) -> None: +def test_fuzz_images(path: pathlib.Path) -> None: fuzzers.enable_decompressionbomb_error() try: - with open(path, "rb") as f: - fuzzers.fuzz_image(f.read()) - assert True + fuzzers.fuzz_image(path.read_bytes()) + assert True except ( # Known exceptions from Pillow OSError, @@ -51,14 +57,13 @@ def test_fuzz_images(path: str) -> None: @skip_unless_feature("freetype2") @pytest.mark.parametrize( - "path", subprocess.check_output("find Tests/fonts -type f", shell=True).split(b"\n") + "path", + find_files("fonts"), + ids=lambda p: str(p.relative_to(tests_path)), ) -def test_fuzz_fonts(path: str) -> None: - if not path: - return - with open(path, "rb") as f: - try: - fuzzers.fuzz_font(f.read()) - except (Image.DecompressionBombError, Image.DecompressionBombWarning, OSError): - pass - assert True +def test_fuzz_fonts(path: pathlib.Path) -> None: + try: + fuzzers.fuzz_font(path.read_bytes()) + except (Image.DecompressionBombError, Image.DecompressionBombWarning, OSError): + pass + assert True From a0c33db717e1bfd0d9aaac8f3b486d9d17f61918 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Tue, 29 Sep 2026 15:49:44 +0300 Subject: [PATCH 2/3] Replace `assert True`s with `pass` --- Tests/oss-fuzz/test_fuzzers.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Tests/oss-fuzz/test_fuzzers.py b/Tests/oss-fuzz/test_fuzzers.py index cb5274f5a14..5ba958ef4f5 100644 --- a/Tests/oss-fuzz/test_fuzzers.py +++ b/Tests/oss-fuzz/test_fuzzers.py @@ -37,7 +37,6 @@ def test_fuzz_images(path: pathlib.Path) -> None: fuzzers.enable_decompressionbomb_error() try: fuzzers.fuzz_image(path.read_bytes()) - assert True except ( # Known exceptions from Pillow OSError, @@ -50,7 +49,7 @@ def test_fuzz_images(path: pathlib.Path) -> None: Image.DecompressionBombError, Image.DecompressionBombWarning, ): - assert True + pass finally: fuzzers.disable_decompressionbomb_error() @@ -66,4 +65,3 @@ def test_fuzz_fonts(path: pathlib.Path) -> None: fuzzers.fuzz_font(path.read_bytes()) except (Image.DecompressionBombError, Image.DecompressionBombWarning, OSError): pass - assert True From ab5234c359ebe1dbe549fea14cc82ec43cf8227d Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Tue, 29 Sep 2026 22:49:18 +1000 Subject: [PATCH 3/3] Use "from pathlib import Path" --- Tests/benchmarks.py | 16 ++++++++-------- Tests/oss-fuzz/test_fuzzers.py | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Tests/benchmarks.py b/Tests/benchmarks.py index d704dbb5af6..b3fd210e991 100644 --- a/Tests/benchmarks.py +++ b/Tests/benchmarks.py @@ -6,11 +6,11 @@ import hashlib import os -import pathlib import re import warnings from importlib.util import find_spec from io import BytesIO +from pathlib import Path import pytest @@ -32,7 +32,7 @@ pytest.skip("pytest-benchmark or pytest-codspeed required", allow_module_level=True) _save_results = os.environ.get("PILLOW_BENCHMARK_SAVE_RESULTS_PATH") -SAVE_RESULTS_PATH = pathlib.Path(_save_results) if _save_results else None +SAVE_RESULTS_PATH = Path(_save_results) if _save_results else None # These can be adjusted to add more modes to benchmark # (however all features benchmarked might not support all PIL modes). @@ -45,7 +45,7 @@ SIZES = [(1237, 811)] # Primes, non-power-of-two, asymmetric, approximately 1024x1024 # For benchmarks that act on test fixture files, these are the paths loaded. -IMAGES_PATH = pathlib.Path(__file__).parent / "images" +IMAGES_PATH = Path(__file__).parent / "images" PATHS = [ IMAGES_PATH / "flower2.jpg", ] @@ -60,7 +60,7 @@ def _format_size(size: tuple[int, int]) -> str: return f"{size[0]}x{size[1]}" -def _format_path(path: pathlib.Path) -> str: +def _format_path(path: Path) -> str: return path.name @@ -569,7 +569,7 @@ def test_draw_lines_blend( @pytest.mark.benchmark(group="load") @pytest.mark.parametrize("path", PATHS, ids=_format_path) -def test_load(bench: BenchmarkFixture, path: pathlib.Path) -> None: +def test_load(bench: BenchmarkFixture, path: Path) -> None: def run() -> None: with Image.open(path) as im: im.load() @@ -579,7 +579,7 @@ def run() -> None: @pytest.mark.benchmark(group="save") @pytest.mark.parametrize("path", PATHS, ids=_format_path) -def test_save_jpeg(bench: BenchmarkFixture, path: pathlib.Path) -> None: +def test_save_jpeg(bench: BenchmarkFixture, path: Path) -> None: with Image.open(path) as im: im.load() bench(lambda: im.save(BytesIO(), format="JPEG", quality=85)) @@ -982,11 +982,11 @@ def test_quantize_to_palette( benchmark_save: BenchmarkSave, dither: Image.Dither, output_mode: str, - source_type: str | pathlib.Path, + source_type: str | Path, palette_type: str, size: tuple[int, int], ) -> None: - if isinstance(source_type, pathlib.Path): + if isinstance(source_type, Path): with Image.open(source_type) as source_im: im = source_im.convert("RGB").resize(size) elif source_type == "synthetic": diff --git a/Tests/oss-fuzz/test_fuzzers.py b/Tests/oss-fuzz/test_fuzzers.py index 5ba958ef4f5..4b2637e7885 100644 --- a/Tests/oss-fuzz/test_fuzzers.py +++ b/Tests/oss-fuzz/test_fuzzers.py @@ -1,7 +1,7 @@ from __future__ import annotations -import pathlib import sys +from pathlib import Path import fuzzers import packaging @@ -21,10 +21,10 @@ reason="Known failing with libjpeg_turbo 2.0" ) -tests_path = pathlib.Path(__file__).parent.parent +tests_path = Path(__file__).parent.parent -def find_files(subdir: str) -> list[pathlib.Path]: +def find_files(subdir: str) -> list[Path]: return [path for path in tests_path.joinpath(subdir).rglob("*") if path.is_file()] @@ -33,7 +33,7 @@ def find_files(subdir: str) -> list[pathlib.Path]: find_files("images"), ids=lambda p: str(p.relative_to(tests_path)), ) -def test_fuzz_images(path: pathlib.Path) -> None: +def test_fuzz_images(path: Path) -> None: fuzzers.enable_decompressionbomb_error() try: fuzzers.fuzz_image(path.read_bytes()) @@ -60,7 +60,7 @@ def test_fuzz_images(path: pathlib.Path) -> None: find_files("fonts"), ids=lambda p: str(p.relative_to(tests_path)), ) -def test_fuzz_fonts(path: pathlib.Path) -> None: +def test_fuzz_fonts(path: Path) -> None: try: fuzzers.fuzz_font(path.read_bytes()) except (Image.DecompressionBombError, Image.DecompressionBombWarning, OSError):