Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import subprocess
import sys
import tempfile
import time
from functools import lru_cache
from io import BytesIO

Expand Down Expand Up @@ -339,3 +340,17 @@ def is_ppc64le() -> bool:

def is_win32() -> bool:
return sys.platform.startswith("win32")


def measure_cpu_seconds(f: Callable[[], Any], times: int = 3) -> float:
"""
Measure the execution time of a function.
"""
best = float("inf")
for _ in range(times):
# `process_time` is the sum of the system and user CPU time
# of the current process, not wallclock time.
start = time.process_time()
f()
best = min(best, time.process_time() - start)
return best
14 changes: 10 additions & 4 deletions Tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
hopper,
is_win32,
mark_if_feature_version,
measure_cpu_seconds,
skip_unless_feature,
timeout_unless_slower_valgrind,
)

TYPE_CHECKING = False
Expand Down Expand Up @@ -571,12 +571,18 @@ def test_check_size(self) -> None:
i = Image.new("RGB", [1, 1])
assert isinstance(i.size, tuple)

@timeout_unless_slower_valgrind(0.75)
@pytest.mark.parametrize(
"size", ((0, 10_000_000), (10_000_000, 0)), ids=("tall", "wide")
"size", ((0, 100_000_000), (100_000_000, 0)), ids=("tall", "wide")
)
def test_empty_image(self, size: tuple[int, int]) -> None:
Image.new("RGB", size)
# Test that initializing an empty image does not do
# extra work to try and fill the image.
# Allocating a tall image can still take a while
# since the internal row pointers are necessarily allocated,
# so measure the difference between doing that work and not doing it.
unfilled = measure_cpu_seconds(lambda: Image.new("RGB", size, None))
filled = measure_cpu_seconds(lambda: Image.new("RGB", size, 0))
assert filled - unfilled < 0.1

def test_storage_neg(self) -> None:
# Storage.c accepted negative values for xsize, ysize. Was
Expand Down