Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added type hints to Tests/check_*.py #7732

Merged
merged 2 commits into from
Jan 21, 2024
Merged
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
2 changes: 1 addition & 1 deletion Tests/check_fli_overflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
TEST_FILE = "Tests/images/fli_overflow.fli"


def test_fli_overflow():
def test_fli_overflow() -> None:
# this should not crash with a malloc error or access violation
with Image.open(TEST_FILE) as im:
im.load()
15 changes: 10 additions & 5 deletions Tests/check_imaging_leaks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env python3
from __future__ import annotations

from typing import Any, Callable

import pytest

from PIL import Image
Expand All @@ -13,31 +15,34 @@
pytestmark = pytest.mark.skipif(is_win32(), reason="requires Unix or macOS")


def _get_mem_usage():
def _get_mem_usage() -> float:
from resource import RUSAGE_SELF, getpagesize, getrusage

mem = getrusage(RUSAGE_SELF).ru_maxrss
return mem * getpagesize() / 1024 / 1024


def _test_leak(min_iterations, max_iterations, fn, *args, **kwargs):
def _test_leak(
min_iterations: int, max_iterations: int, fn: Callable[..., None], *args: Any
) -> None:
mem_limit = None
for i in range(max_iterations):
fn(*args, **kwargs)
fn(*args)
mem = _get_mem_usage()
if i < min_iterations:
mem_limit = mem + 1
continue
msg = f"memory usage limit exceeded after {i + 1} iterations"
assert mem_limit is not None
assert mem <= mem_limit, msg


def test_leak_putdata():
def test_leak_putdata() -> None:
im = Image.new("RGB", (25, 25))
_test_leak(min_iterations, max_iterations, im.putdata, im.getdata())


def test_leak_getlist():
def test_leak_getlist() -> None:
im = Image.new("P", (25, 25))
_test_leak(
min_iterations,
Expand Down
4 changes: 2 additions & 2 deletions Tests/check_j2k_leaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
]


def test_leak_load():
def test_leak_load() -> None:
from resource import RLIMIT_AS, RLIMIT_STACK, setrlimit

setrlimit(RLIMIT_STACK, (stack_size, stack_size))
Expand All @@ -30,7 +30,7 @@ def test_leak_load():
im.load()


def test_leak_save():
def test_leak_save() -> None:
from resource import RLIMIT_AS, RLIMIT_STACK, setrlimit

setrlimit(RLIMIT_STACK, (stack_size, stack_size))
Expand Down
4 changes: 3 additions & 1 deletion Tests/check_j2k_overflow.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from __future__ import annotations

from pathlib import PosixPath

import pytest

from PIL import Image


def test_j2k_overflow(tmp_path):
def test_j2k_overflow(tmp_path: PosixPath) -> None:
im = Image.new("RGBA", (1024, 131584))
target = str(tmp_path / "temp.jpc")
with pytest.raises(OSError):
Expand Down
6 changes: 3 additions & 3 deletions Tests/check_jpeg_leaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,14 @@
[standard_l_qtable, standard_chrominance_qtable],
),
)
def test_qtables_leak(qtables):
def test_qtables_leak(qtables: tuple[tuple[int, ...]] | list[tuple[int, ...]]) -> None:
im = hopper("RGB")
for _ in range(iterations):
test_output = BytesIO()
im.save(test_output, "JPEG", qtables=qtables)


def test_exif_leak():
def test_exif_leak() -> None:
"""
pre patch:

Expand Down Expand Up @@ -181,7 +181,7 @@ def test_exif_leak():
im.save(test_output, "JPEG", exif=exif)


def test_base_save():
def test_base_save() -> None:
"""
base case:
MB
Expand Down
12 changes: 8 additions & 4 deletions Tests/check_large_memory.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from __future__ import annotations

import sys
from pathlib import PosixPath
from types import ModuleType

import pytest

Expand All @@ -16,6 +18,7 @@
# 2.7 and 3.2.


numpy: ModuleType | None
try:
import numpy
except ImportError:
Expand All @@ -28,23 +31,24 @@
pytestmark = pytest.mark.skipif(sys.maxsize <= 2**32, reason="requires 64-bit system")


def _write_png(tmp_path, xdim, ydim):
def _write_png(tmp_path: PosixPath, xdim: int, ydim: int) -> None:
f = str(tmp_path / "temp.png")
im = Image.new("L", (xdim, ydim), 0)
im.save(f)


def test_large(tmp_path):
def test_large(tmp_path: PosixPath) -> None:
"""succeeded prepatch"""
_write_png(tmp_path, XDIM, YDIM)


def test_2gpx(tmp_path):
def test_2gpx(tmp_path: PosixPath) -> None:
"""failed prepatch"""
_write_png(tmp_path, XDIM, XDIM)


@pytest.mark.skipif(numpy is None, reason="Numpy is not installed")
def test_size_greater_than_int():
def test_size_greater_than_int() -> None:
assert numpy is not None
arr = numpy.ndarray(shape=(16394, 16394))
Image.fromarray(arr)
7 changes: 4 additions & 3 deletions Tests/check_large_memory_numpy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import sys
from pathlib import PosixPath

import pytest

Expand All @@ -24,19 +25,19 @@
pytestmark = pytest.mark.skipif(sys.maxsize <= 2**32, reason="requires 64-bit system")


def _write_png(tmp_path, xdim, ydim):
def _write_png(tmp_path: PosixPath, xdim: int, ydim: int) -> None:
dtype = np.uint8
a = np.zeros((xdim, ydim), dtype=dtype)
f = str(tmp_path / "temp.png")
im = Image.fromarray(a, "L")
im.save(f)


def test_large(tmp_path):
def test_large(tmp_path: PosixPath) -> None:
"""succeeded prepatch"""
_write_png(tmp_path, XDIM, YDIM)


def test_2gpx(tmp_path):
def test_2gpx(tmp_path: PosixPath) -> None:
"""failed prepatch"""
_write_png(tmp_path, XDIM, XDIM)
2 changes: 1 addition & 1 deletion Tests/check_libtiff_segfault.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
TEST_FILE = "Tests/images/libtiff_segfault.tif"


def test_libtiff_segfault():
def test_libtiff_segfault() -> None:
"""This test should not segfault. It will on Pillow <= 3.1.0 and
libtiff >= 4.0.0
"""
Expand Down
8 changes: 4 additions & 4 deletions Tests/check_png_dos.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
TEST_FILE = "Tests/images/png_decompression_dos.png"


def test_ignore_dos_text():
def test_ignore_dos_text() -> None:
ImageFile.LOAD_TRUNCATED_IMAGES = True

try:
Expand All @@ -24,7 +24,7 @@ def test_ignore_dos_text():
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"


def test_dos_text():
def test_dos_text() -> None:
try:
im = Image.open(TEST_FILE)
im.load()
Expand All @@ -36,7 +36,7 @@ def test_dos_text():
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"


def test_dos_total_memory():
def test_dos_total_memory() -> None:
im = Image.new("L", (1, 1))
compressed_data = zlib.compress(b"a" * 1024 * 1023)

Expand All @@ -53,7 +53,7 @@ def test_dos_total_memory():
try:
im2 = Image.open(b)
except ValueError as msg:
assert "Too much memory" in msg
assert "Too much memory" in str(msg)
return

total_len = 0
Expand Down
6 changes: 3 additions & 3 deletions Tests/check_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from PIL import features


def test_wheel_modules():
def test_wheel_modules() -> None:
expected_modules = {"pil", "tkinter", "freetype2", "littlecms2", "webp"}

# tkinter is not available in cibuildwheel installed CPython on Windows
Expand All @@ -19,13 +19,13 @@ def test_wheel_modules():
assert set(features.get_supported_modules()) == expected_modules


def test_wheel_codecs():
def test_wheel_codecs() -> None:
expected_codecs = {"jpg", "jpg_2000", "zlib", "libtiff"}

assert set(features.get_supported_codecs()) == expected_codecs


def test_wheel_features():
def test_wheel_features() -> None:
expected_features = {
"webp_anim",
"webp_mux",
Expand Down