Added type hints

This commit is contained in:
Andrew Murray 2024-06-24 06:59:00 +10:00
parent 920698eea7
commit 42381aa1e6
14 changed files with 57 additions and 27 deletions

View File

@ -64,6 +64,9 @@ def test_handler(tmp_path: Path) -> None:
im.fp.close() im.fp.close()
return Image.new("RGB", (1, 1)) return Image.new("RGB", (1, 1))
def is_loaded(self) -> bool:
return self.loaded
def save(self, im: Image.Image, fp: IO[bytes], filename: str) -> None: def save(self, im: Image.Image, fp: IO[bytes], filename: str) -> None:
self.saved = True self.saved = True
@ -71,10 +74,10 @@ def test_handler(tmp_path: Path) -> None:
BufrStubImagePlugin.register_handler(handler) BufrStubImagePlugin.register_handler(handler)
with Image.open(TEST_FILE) as im: with Image.open(TEST_FILE) as im:
assert handler.opened assert handler.opened
assert not handler.loaded assert not handler.is_loaded()
im.load() im.load()
assert handler.loaded assert handler.is_loaded()
temp_file = str(tmp_path / "temp.bufr") temp_file = str(tmp_path / "temp.bufr")
im.save(temp_file) im.save(temp_file)

View File

@ -64,6 +64,9 @@ def test_handler(tmp_path: Path) -> None:
im.fp.close() im.fp.close()
return Image.new("RGB", (1, 1)) return Image.new("RGB", (1, 1))
def is_loaded(self) -> bool:
return self.loaded
def save(self, im: Image.Image, fp: IO[bytes], filename: str) -> None: def save(self, im: Image.Image, fp: IO[bytes], filename: str) -> None:
self.saved = True self.saved = True
@ -71,10 +74,10 @@ def test_handler(tmp_path: Path) -> None:
GribStubImagePlugin.register_handler(handler) GribStubImagePlugin.register_handler(handler)
with Image.open(TEST_FILE) as im: with Image.open(TEST_FILE) as im:
assert handler.opened assert handler.opened
assert not handler.loaded assert not handler.is_loaded()
im.load() im.load()
assert handler.loaded assert handler.is_loaded()
temp_file = str(tmp_path / "temp.grib") temp_file = str(tmp_path / "temp.grib")
im.save(temp_file) im.save(temp_file)

View File

@ -66,6 +66,9 @@ def test_handler(tmp_path: Path) -> None:
im.fp.close() im.fp.close()
return Image.new("RGB", (1, 1)) return Image.new("RGB", (1, 1))
def is_loaded(self) -> bool:
return self.loaded
def save(self, im: Image.Image, fp: IO[bytes], filename: str) -> None: def save(self, im: Image.Image, fp: IO[bytes], filename: str) -> None:
self.saved = True self.saved = True
@ -73,10 +76,10 @@ def test_handler(tmp_path: Path) -> None:
Hdf5StubImagePlugin.register_handler(handler) Hdf5StubImagePlugin.register_handler(handler)
with Image.open(TEST_FILE) as im: with Image.open(TEST_FILE) as im:
assert handler.opened assert handler.opened
assert not handler.loaded assert not handler.is_loaded()
im.load() im.load()
assert handler.loaded assert handler.is_loaded()
temp_file = str(tmp_path / "temp.h5") temp_file = str(tmp_path / "temp.h5")
im.save(temp_file) im.save(temp_file)

View File

@ -775,7 +775,7 @@ class TestFilePng:
mystdout: MyStdOut | BytesIO = MyStdOut() if buffer else BytesIO() mystdout: MyStdOut | BytesIO = MyStdOut() if buffer else BytesIO()
sys.stdout = mystdout sys.stdout = mystdout # type: ignore[assignment]
with Image.open(TEST_PNG_FILE) as im: with Image.open(TEST_PNG_FILE) as im:
im.save(sys.stdout, "PNG") im.save(sys.stdout, "PNG")

View File

@ -373,7 +373,7 @@ def test_save_stdout(buffer: bool) -> None:
mystdout: MyStdOut | BytesIO = MyStdOut() if buffer else BytesIO() mystdout: MyStdOut | BytesIO = MyStdOut() if buffer else BytesIO()
sys.stdout = mystdout sys.stdout = mystdout # type: ignore[assignment]
with Image.open(TEST_FILE) as im: with Image.open(TEST_FILE) as im:
im.save(sys.stdout, "PPM") im.save(sys.stdout, "PPM")

View File

@ -162,7 +162,7 @@ def test_combined_larger_than_size() -> None:
("Tests/images/timeout-dedc7a4ebd856d79b4359bbcc79e8ef231ce38f6.psd", OSError), ("Tests/images/timeout-dedc7a4ebd856d79b4359bbcc79e8ef231ce38f6.psd", OSError),
], ],
) )
def test_crashes(test_file: str, raises) -> None: def test_crashes(test_file: str, raises: type[Exception]) -> None:
with open(test_file, "rb") as f: with open(test_file, "rb") as f:
with pytest.raises(raises): with pytest.raises(raises):
with Image.open(f): with Image.open(f):

View File

@ -11,7 +11,11 @@ from PIL.TiffImagePlugin import IFDRational
from .helper import assert_deep_equal, hopper from .helper import assert_deep_equal, hopper
TAG_IDS = {info.name: info.value for info in TiffTags.TAGS_V2.values()} TAG_IDS: dict[str, int] = {
info.name: info.value
for info in TiffTags.TAGS_V2.values()
if info.value is not None
}
def test_rt_metadata(tmp_path: Path) -> None: def test_rt_metadata(tmp_path: Path) -> None:
@ -411,8 +415,8 @@ def test_empty_values() -> None:
info = TiffImagePlugin.ImageFileDirectory_v2(head) info = TiffImagePlugin.ImageFileDirectory_v2(head)
info.load(data) info.load(data)
# Should not raise ValueError. # Should not raise ValueError.
info = dict(info) info_dict = dict(info)
assert 33432 in info assert 33432 in info_dict
def test_photoshop_info(tmp_path: Path) -> None: def test_photoshop_info(tmp_path: Path) -> None:

View File

@ -5,6 +5,7 @@ import re
import sys import sys
import warnings import warnings
from pathlib import Path from pathlib import Path
from typing import Any
import pytest import pytest
@ -70,7 +71,9 @@ class TestFileWebp:
# dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm # dwebp -ppm ../../Tests/images/hopper.webp -o hopper_webp_bits.ppm
assert_image_similar_tofile(image, "Tests/images/hopper_webp_bits.ppm", 1.0) assert_image_similar_tofile(image, "Tests/images/hopper_webp_bits.ppm", 1.0)
def _roundtrip(self, tmp_path: Path, mode, epsilon, args={}) -> None: def _roundtrip(
self, tmp_path: Path, mode: str, epsilon: float, args: dict[str, Any] = {}
) -> None:
temp_file = str(tmp_path / "temp.webp") temp_file = str(tmp_path / "temp.webp")
hopper(mode).save(temp_file, **args) hopper(mode).save(temp_file, **args)

View File

@ -8,7 +8,7 @@ import sys
import tempfile import tempfile
import warnings import warnings
from pathlib import Path from pathlib import Path
from typing import IO from typing import IO, Any
import pytest import pytest
@ -175,11 +175,19 @@ class TestImage:
def test_fp_name(self, tmp_path: Path) -> None: def test_fp_name(self, tmp_path: Path) -> None:
temp_file = str(tmp_path / "temp.jpg") temp_file = str(tmp_path / "temp.jpg")
class FP: class FP(io.BytesIO):
name: str name: str
def write(self, b: bytes) -> None: if sys.version_info >= (3, 12):
pass from collections.abc import Buffer
def write(self, data: Buffer) -> int:
return len(data)
else:
def write(self, data: Any) -> int:
return len(data)
fp = FP() fp = FP()
fp.name = temp_file fp.name = temp_file

View File

@ -1,6 +1,6 @@
from __future__ import annotations from __future__ import annotations
from typing import Any from typing import TYPE_CHECKING, Any
import pytest import pytest
from packaging.version import parse as parse_version from packaging.version import parse as parse_version
@ -13,13 +13,16 @@ numpy = pytest.importorskip("numpy", reason="NumPy not installed")
im = hopper().resize((128, 100)) im = hopper().resize((128, 100))
if TYPE_CHECKING:
import numpy.typing as npt
def test_toarray() -> None: def test_toarray() -> None:
def test(mode: str) -> tuple[tuple[int, ...], str, int]: def test(mode: str) -> tuple[tuple[int, ...], str, int]:
ai = numpy.array(im.convert(mode)) ai = numpy.array(im.convert(mode))
return ai.shape, ai.dtype.str, ai.nbytes return ai.shape, ai.dtype.str, ai.nbytes
def test_with_dtype(dtype) -> None: def test_with_dtype(dtype: npt.DTypeLike) -> None:
ai = numpy.array(im, dtype=dtype) ai = numpy.array(im, dtype=dtype)
assert ai.dtype == dtype assert ai.dtype == dtype

View File

@ -351,7 +351,9 @@ class TestPyEncoder(CodecsTest):
ImageFile._save( ImageFile._save(
im, fp, [("MOCK", (xoff, yoff, -10, yoff + ysize), 0, "RGB")] im, fp, [("MOCK", (xoff, yoff, -10, yoff + ysize), 0, "RGB")]
) )
assert MockPyEncoder.last.cleanup_called last: MockPyEncoder | None = MockPyEncoder.last
assert last
assert last.cleanup_called
with pytest.raises(ValueError): with pytest.raises(ValueError):
ImageFile._save( ImageFile._save(

View File

@ -548,7 +548,7 @@ def test_find_font(
def loadable_font( def loadable_font(
filepath: str, size: int, index: int, encoding: str, *args: Any filepath: str, size: int, index: int, encoding: str, *args: Any
): ) -> ImageFont.FreeTypeFont:
_freeTypeFont = getattr(ImageFont, "_FreeTypeFont") _freeTypeFont = getattr(ImageFont, "_FreeTypeFont")
if filepath == path_to_fake: if filepath == path_to_fake:
return _freeTypeFont(FONT_PATH, size, index, encoding, *args) return _freeTypeFont(FONT_PATH, size, index, encoding, *args)

View File

@ -45,21 +45,22 @@ if is_win32():
memcpy = ctypes.cdll.msvcrt.memcpy memcpy = ctypes.cdll.msvcrt.memcpy
memcpy.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t] memcpy.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t]
CreateCompatibleDC = ctypes.windll.gdi32.CreateCompatibleDC windll = getattr(ctypes, "windll")
CreateCompatibleDC = windll.gdi32.CreateCompatibleDC
CreateCompatibleDC.argtypes = [ctypes.wintypes.HDC] CreateCompatibleDC.argtypes = [ctypes.wintypes.HDC]
CreateCompatibleDC.restype = ctypes.wintypes.HDC CreateCompatibleDC.restype = ctypes.wintypes.HDC
DeleteDC = ctypes.windll.gdi32.DeleteDC DeleteDC = windll.gdi32.DeleteDC
DeleteDC.argtypes = [ctypes.wintypes.HDC] DeleteDC.argtypes = [ctypes.wintypes.HDC]
SelectObject = ctypes.windll.gdi32.SelectObject SelectObject = windll.gdi32.SelectObject
SelectObject.argtypes = [ctypes.wintypes.HDC, ctypes.wintypes.HGDIOBJ] SelectObject.argtypes = [ctypes.wintypes.HDC, ctypes.wintypes.HGDIOBJ]
SelectObject.restype = ctypes.wintypes.HGDIOBJ SelectObject.restype = ctypes.wintypes.HGDIOBJ
DeleteObject = ctypes.windll.gdi32.DeleteObject DeleteObject = windll.gdi32.DeleteObject
DeleteObject.argtypes = [ctypes.wintypes.HGDIOBJ] DeleteObject.argtypes = [ctypes.wintypes.HGDIOBJ]
CreateDIBSection = ctypes.windll.gdi32.CreateDIBSection CreateDIBSection = windll.gdi32.CreateDIBSection
CreateDIBSection.argtypes = [ CreateDIBSection.argtypes = [
ctypes.wintypes.HDC, ctypes.wintypes.HDC,
ctypes.c_void_p, ctypes.c_void_p,

View File

@ -59,7 +59,7 @@ def test_stdout(buffer: bool) -> None:
mystdout: MyStdOut | BytesIO = MyStdOut() if buffer else BytesIO() mystdout: MyStdOut | BytesIO = MyStdOut() if buffer else BytesIO()
sys.stdout = mystdout sys.stdout = mystdout # type: ignore[assignment]
ps = PSDraw.PSDraw() ps = PSDraw.PSDraw()
_create_document(ps) _create_document(ps)