Added type hints

This commit is contained in:
Andrew Murray 2024-06-18 23:03:03 +10:00
parent 8d8852d744
commit 291ee35204
6 changed files with 28 additions and 18 deletions

View File

@ -701,7 +701,7 @@ class TestFileJpeg:
def test_save_cjpeg(self, tmp_path: Path) -> None: def test_save_cjpeg(self, tmp_path: Path) -> None:
with Image.open(TEST_FILE) as img: with Image.open(TEST_FILE) as img:
tempfile = str(tmp_path / "temp.jpg") tempfile = str(tmp_path / "temp.jpg")
JpegImagePlugin._save_cjpeg(img, 0, tempfile) JpegImagePlugin._save_cjpeg(img, BytesIO(), tempfile)
# Default save quality is 75%, so a tiny bit of difference is alright # Default save quality is 75%, so a tiny bit of difference is alright
assert_image_similar_tofile(img, tempfile, 17) assert_image_similar_tofile(img, tempfile, 17)

View File

@ -460,7 +460,7 @@ def test_plt_marker() -> None:
out.seek(length - 2, os.SEEK_CUR) out.seek(length - 2, os.SEEK_CUR)
def test_9bit(): def test_9bit() -> None:
with Image.open("Tests/images/9bit.j2k") as im: with Image.open("Tests/images/9bit.j2k") as im:
assert im.mode == "I;16" assert im.mode == "I;16"
assert im.size == (128, 128) assert im.size == (128, 128)

View File

@ -152,7 +152,7 @@ class TestImage:
def test_stringio(self) -> None: def test_stringio(self) -> None:
with pytest.raises(ValueError): with pytest.raises(ValueError):
with Image.open(io.StringIO()): with Image.open(io.StringIO()): # type: ignore[arg-type]
pass pass
def test_pathlib(self, tmp_path: Path) -> None: def test_pathlib(self, tmp_path: Path) -> None:

View File

@ -113,13 +113,13 @@ def test_array_F() -> None:
def test_not_flattened() -> None: def test_not_flattened() -> None:
im = Image.new("L", (1, 1)) im = Image.new("L", (1, 1))
with pytest.raises(TypeError): with pytest.raises(TypeError):
im.putdata([[0]]) im.putdata([[0]]) # type: ignore[list-item]
with pytest.raises(TypeError): with pytest.raises(TypeError):
im.putdata([[0]], 2) im.putdata([[0]], 2) # type: ignore[list-item]
with pytest.raises(TypeError): with pytest.raises(TypeError):
im = Image.new("I", (1, 1)) im = Image.new("I", (1, 1))
im.putdata([[0]]) im.putdata([[0]]) # type: ignore[list-item]
with pytest.raises(TypeError): with pytest.raises(TypeError):
im = Image.new("F", (1, 1)) im = Image.new("F", (1, 1))
im.putdata([[0]]) im.putdata([[0]]) # type: ignore[list-item]

View File

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
import warnings import warnings
from typing import TYPE_CHECKING, Any
import pytest import pytest
@ -8,13 +9,19 @@ from PIL import Image
from .helper import assert_deep_equal, assert_image, hopper, skip_unless_feature from .helper import assert_deep_equal, assert_image, hopper, skip_unless_feature
numpy = pytest.importorskip("numpy", reason="NumPy not installed") if TYPE_CHECKING:
import numpy
import numpy.typing
else:
numpy = pytest.importorskip("numpy", reason="NumPy not installed")
TEST_IMAGE_SIZE = (10, 10) TEST_IMAGE_SIZE = (10, 10)
def test_numpy_to_image() -> None: def test_numpy_to_image() -> None:
def to_image(dtype, bands: int = 1, boolean: int = 0) -> Image.Image: def to_image(
dtype: numpy.typing.DTypeLike, bands: int = 1, boolean: int = 0
) -> Image.Image:
if bands == 1: if bands == 1:
if boolean: if boolean:
data = [0, 255] * 50 data = [0, 255] * 50
@ -99,14 +106,16 @@ def test_1d_array() -> None:
assert_image(Image.fromarray(a), "L", (1, 5)) assert_image(Image.fromarray(a), "L", (1, 5))
def _test_img_equals_nparray(img: Image.Image, np) -> None: def _test_img_equals_nparray(
assert len(np.shape) >= 2 img: Image.Image, np_img: numpy.typing.NDArray[Any]
np_size = np.shape[1], np.shape[0] ) -> None:
assert len(np_img.shape) >= 2
np_size = np_img.shape[1], np_img.shape[0]
assert img.size == np_size assert img.size == np_size
px = img.load() px = img.load()
for x in range(0, img.size[0], int(img.size[0] / 10)): for x in range(0, img.size[0], int(img.size[0] / 10)):
for y in range(0, img.size[1], int(img.size[1] / 10)): for y in range(0, img.size[1], int(img.size[1] / 10)):
assert_deep_equal(px[x, y], np[y, x]) assert_deep_equal(px[x, y], np_img[y, x])
def test_16bit() -> None: def test_16bit() -> None:
@ -157,7 +166,7 @@ def test_save_tiff_uint16() -> None:
("HSV", numpy.uint8), ("HSV", numpy.uint8),
), ),
) )
def test_to_array(mode: str, dtype) -> None: def test_to_array(mode: str, dtype: numpy.typing.DTypeLike) -> None:
img = hopper(mode) img = hopper(mode)
# Resize to non-square # Resize to non-square
@ -207,7 +216,7 @@ def test_putdata() -> None:
numpy.float64, numpy.float64,
), ),
) )
def test_roundtrip_eye(dtype) -> None: def test_roundtrip_eye(dtype: numpy.typing.DTypeLike) -> None:
arr = numpy.eye(10, dtype=dtype) arr = numpy.eye(10, dtype=dtype)
numpy.testing.assert_array_equal(arr, numpy.array(Image.fromarray(arr))) numpy.testing.assert_array_equal(arr, numpy.array(Image.fromarray(arr)))

View File

@ -1,8 +1,9 @@
from __future__ import annotations from __future__ import annotations
import shutil import shutil
from io import BytesIO
from pathlib import Path from pathlib import Path
from typing import Callable from typing import IO, Callable
import pytest import pytest
@ -22,11 +23,11 @@ class TestShellInjection:
self, self,
tmp_path: Path, tmp_path: Path,
src_img: Image.Image, src_img: Image.Image,
save_func: Callable[[Image.Image, int, str], None], save_func: Callable[[Image.Image, IO[bytes], str | bytes], None],
) -> None: ) -> None:
for filename in test_filenames: for filename in test_filenames:
dest_file = str(tmp_path / filename) dest_file = str(tmp_path / filename)
save_func(src_img, 0, dest_file) save_func(src_img, BytesIO(), dest_file)
# If file can't be opened, shell injection probably occurred # If file can't be opened, shell injection probably occurred
with Image.open(dest_file) as im: with Image.open(dest_file) as im:
im.load() im.load()