mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 17:36:18 +03:00
Added type hints
This commit is contained in:
parent
380bc1766b
commit
e39765d755
|
@ -20,7 +20,7 @@ from PIL import _deprecate
|
|||
),
|
||||
],
|
||||
)
|
||||
def test_version(version, expected) -> None:
|
||||
def test_version(version: int | None, expected: str) -> None:
|
||||
with pytest.warns(DeprecationWarning, match=expected):
|
||||
_deprecate.deprecate("Old thing", version, "new thing")
|
||||
|
||||
|
@ -46,7 +46,7 @@ def test_unknown_version() -> None:
|
|||
),
|
||||
],
|
||||
)
|
||||
def test_old_version(deprecated, plural, expected) -> None:
|
||||
def test_old_version(deprecated: str, plural: bool, expected: str) -> None:
|
||||
expected = r""
|
||||
with pytest.raises(RuntimeError, match=expected):
|
||||
_deprecate.deprecate(deprecated, 1, plural=plural)
|
||||
|
@ -76,7 +76,7 @@ def test_replacement_and_action() -> None:
|
|||
"Upgrade to new thing.",
|
||||
],
|
||||
)
|
||||
def test_action(action) -> None:
|
||||
def test_action(action: str) -> None:
|
||||
expected = (
|
||||
r"Old thing is deprecated and will be removed in Pillow 11 \(2024-10-15\)\. "
|
||||
r"Upgrade to new thing\."
|
||||
|
|
|
@ -135,7 +135,7 @@ def test_different_bit_depths(tmp_path: Path) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("mode", ("1", "L", "P", "RGB", "RGBA"))
|
||||
def test_save_to_bytes_bmp(mode) -> None:
|
||||
def test_save_to_bytes_bmp(mode: str) -> None:
|
||||
output = io.BytesIO()
|
||||
im = hopper(mode)
|
||||
im.save(output, "ico", bitmap_format="bmp", sizes=[(32, 32), (64, 64)])
|
||||
|
|
|
@ -98,7 +98,7 @@ def test_i() -> None:
|
|||
assert ret == 97
|
||||
|
||||
|
||||
def test_dump(monkeypatch) -> None:
|
||||
def test_dump(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
# Arrange
|
||||
c = b"abc"
|
||||
# Temporarily redirect stdout
|
||||
|
|
|
@ -52,7 +52,7 @@ def test_open_windows_v1() -> None:
|
|||
assert isinstance(im, MspImagePlugin.MspImageFile)
|
||||
|
||||
|
||||
def _assert_file_image_equal(source_path, target_path) -> None:
|
||||
def _assert_file_image_equal(source_path: str, target_path: str) -> None:
|
||||
with Image.open(source_path) as im:
|
||||
assert_image_equal_tofile(im, target_path)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import warnings
|
|||
import zlib
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
@ -23,6 +24,7 @@ from .helper import (
|
|||
skip_unless_feature,
|
||||
)
|
||||
|
||||
ElementTree: ModuleType | None
|
||||
try:
|
||||
from defusedxml import ElementTree
|
||||
except ImportError:
|
||||
|
|
|
@ -157,7 +157,7 @@ def test_combined_larger_than_size() -> None:
|
|||
("Tests/images/timeout-dedc7a4ebd856d79b4359bbcc79e8ef231ce38f6.psd", OSError),
|
||||
],
|
||||
)
|
||||
def test_crashes(test_file, raises) -> None:
|
||||
def test_crashes(test_file: str, raises) -> None:
|
||||
with open(test_file, "rb") as f:
|
||||
with pytest.raises(raises):
|
||||
with Image.open(f):
|
||||
|
|
|
@ -22,8 +22,8 @@ _ORIGIN_TO_ORIENTATION = {"tl": 1, "bl": -1}
|
|||
|
||||
|
||||
@pytest.mark.parametrize("mode", _MODES)
|
||||
def test_sanity(mode, tmp_path: Path) -> None:
|
||||
def roundtrip(original_im) -> None:
|
||||
def test_sanity(mode: str, tmp_path: Path) -> None:
|
||||
def roundtrip(original_im: Image.Image) -> None:
|
||||
out = str(tmp_path / "temp.tga")
|
||||
|
||||
original_im.save(out, rle=rle)
|
||||
|
|
|
@ -189,7 +189,9 @@ def test_iptc(tmp_path: Path) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("value, expected", ((b"test", "test"), (1, "1")))
|
||||
def test_writing_other_types_to_ascii(value, expected, tmp_path: Path) -> None:
|
||||
def test_writing_other_types_to_ascii(
|
||||
value: bytes | int, expected: str, tmp_path: Path
|
||||
) -> None:
|
||||
info = TiffImagePlugin.ImageFileDirectory_v2()
|
||||
|
||||
tag = TiffTags.TAGS_V2[271]
|
||||
|
@ -206,7 +208,7 @@ def test_writing_other_types_to_ascii(value, expected, tmp_path: Path) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("value", (1, IFDRational(1)))
|
||||
def test_writing_other_types_to_bytes(value, tmp_path: Path) -> None:
|
||||
def test_writing_other_types_to_bytes(value: int | IFDRational, tmp_path: Path) -> None:
|
||||
im = hopper()
|
||||
info = TiffImagePlugin.ImageFileDirectory_v2()
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ def test_invalid_color_temperature() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("flag", ("my string", -1))
|
||||
def test_invalid_flag(flag) -> None:
|
||||
def test_invalid_flag(flag: str | int) -> None:
|
||||
with hopper() as im:
|
||||
with pytest.raises(
|
||||
ImageCms.PyCMSError, match="flags must be an integer between 0 and "
|
||||
|
@ -335,12 +335,26 @@ def test_extended_information() -> None:
|
|||
o = ImageCms.getOpenProfile(SRGB)
|
||||
p = o.profile
|
||||
|
||||
def assert_truncated_tuple_equal(tup1, tup2, digits: int = 10) -> None:
|
||||
def assert_truncated_tuple_equal(
|
||||
tup1: tuple[tuple[float, float, float], ...] | tuple[float],
|
||||
tup2: (
|
||||
tuple[tuple[tuple[float, float, float], ...], ...]
|
||||
| tuple[tuple[float, float, float], ...]
|
||||
| tuple[float]
|
||||
),
|
||||
digits: int = 10,
|
||||
) -> None:
|
||||
# Helper function to reduce precision of tuples of floats
|
||||
# recursively and then check equality.
|
||||
power = 10**digits
|
||||
|
||||
def truncate_tuple(tuple_or_float):
|
||||
def truncate_tuple(
|
||||
tuple_or_float: (
|
||||
tuple[tuple[tuple[float, float, float], ...], ...]
|
||||
| tuple[tuple[float, float, float], ...]
|
||||
| tuple[float, ...]
|
||||
)
|
||||
) -> tuple[tuple[float, ...], ...]:
|
||||
return tuple(
|
||||
(
|
||||
truncate_tuple(val)
|
||||
|
@ -504,8 +518,10 @@ def test_profile_typesafety() -> None:
|
|||
ImageCms.ImageCmsProfile(1).tobytes()
|
||||
|
||||
|
||||
def assert_aux_channel_preserved(mode, transform_in_place, preserved_channel) -> None:
|
||||
def create_test_image():
|
||||
def assert_aux_channel_preserved(
|
||||
mode: str, transform_in_place: bool, preserved_channel: str
|
||||
) -> None:
|
||||
def create_test_image() -> Image.Image:
|
||||
# set up test image with something interesting in the tested aux channel.
|
||||
# fmt: off
|
||||
nine_grid_deltas = [
|
||||
|
@ -633,7 +649,7 @@ def test_auxiliary_channels_isolated() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("mode", ("RGB", "RGBA", "RGBX"))
|
||||
def test_rgb_lab(mode) -> None:
|
||||
def test_rgb_lab(mode: str) -> None:
|
||||
im = Image.new(mode, (1, 1))
|
||||
converted_im = im.convert("LAB")
|
||||
assert converted_im.getpixel((0, 0)) == (0, 128, 128)
|
||||
|
|
|
@ -7,7 +7,7 @@ import shutil
|
|||
import sys
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from typing import BinaryIO
|
||||
from typing import Any, BinaryIO
|
||||
|
||||
import pytest
|
||||
from packaging.version import parse as parse_version
|
||||
|
@ -44,7 +44,7 @@ def test_sanity() -> None:
|
|||
pytest.param(ImageFont.Layout.RAQM, marks=skip_unless_feature("raqm")),
|
||||
],
|
||||
)
|
||||
def layout_engine(request):
|
||||
def layout_engine(request: pytest.FixtureRequest) -> ImageFont.Layout:
|
||||
return request.param
|
||||
|
||||
|
||||
|
@ -535,21 +535,23 @@ def test_unicode_extended(layout_engine: ImageFont.Layout) -> None:
|
|||
(("linux", "/usr/local/share/fonts"), ("darwin", "/System/Library/Fonts")),
|
||||
)
|
||||
@pytest.mark.skipif(is_win32(), reason="requires Unix or macOS")
|
||||
def test_find_font(monkeypatch, platform, font_directory) -> None:
|
||||
def test_find_font(
|
||||
monkeypatch: pytest.MonkeyPatch, platform: str, font_directory: str
|
||||
) -> None:
|
||||
def _test_fake_loading_font(path_to_fake: str, fontname: str) -> None:
|
||||
# Make a copy of FreeTypeFont so we can patch the original
|
||||
free_type_font = copy.deepcopy(ImageFont.FreeTypeFont)
|
||||
with monkeypatch.context() as m:
|
||||
m.setattr(ImageFont, "_FreeTypeFont", free_type_font, raising=False)
|
||||
|
||||
def loadable_font(filepath, size, index, encoding, *args, **kwargs):
|
||||
def loadable_font(
|
||||
filepath: str, size: int, index: int, encoding: str, *args: Any
|
||||
):
|
||||
if filepath == path_to_fake:
|
||||
return ImageFont._FreeTypeFont(
|
||||
FONT_PATH, size, index, encoding, *args, **kwargs
|
||||
FONT_PATH, size, index, encoding, *args
|
||||
)
|
||||
return ImageFont._FreeTypeFont(
|
||||
filepath, size, index, encoding, *args, **kwargs
|
||||
)
|
||||
return ImageFont._FreeTypeFont(filepath, size, index, encoding, *args)
|
||||
|
||||
m.setattr(ImageFont, "FreeTypeFont", loadable_font)
|
||||
font = ImageFont.truetype(fontname)
|
||||
|
@ -563,7 +565,7 @@ def test_find_font(monkeypatch, platform, font_directory) -> None:
|
|||
if platform == "linux":
|
||||
monkeypatch.setenv("XDG_DATA_DIRS", "/usr/share/:/usr/local/share/")
|
||||
|
||||
def fake_walker(path):
|
||||
def fake_walker(path: str) -> list[tuple[str, list[str], list[str]]]:
|
||||
if path == font_directory:
|
||||
return [
|
||||
(
|
||||
|
@ -1101,7 +1103,7 @@ def test_oom(test_file: str) -> None:
|
|||
font.getmask("Test Text")
|
||||
|
||||
|
||||
def test_raqm_missing_warning(monkeypatch) -> None:
|
||||
def test_raqm_missing_warning(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(ImageFont.core, "HAVE_RAQM", False)
|
||||
with pytest.warns(UserWarning) as record:
|
||||
font = ImageFont.truetype(
|
||||
|
|
|
@ -84,6 +84,7 @@ $bmp = New-Object Drawing.Bitmap 200, 200
|
|||
@pytest.mark.skipif(sys.platform != "win32", reason="Windows only")
|
||||
def test_grabclipboard_file(self) -> None:
|
||||
p = subprocess.Popen(["powershell", "-command", "-"], stdin=subprocess.PIPE)
|
||||
assert p.stdin is not None
|
||||
p.stdin.write(rb'Set-Clipboard -Path "Tests\images\hopper.gif"')
|
||||
p.communicate()
|
||||
|
||||
|
@ -94,6 +95,7 @@ $bmp = New-Object Drawing.Bitmap 200, 200
|
|||
@pytest.mark.skipif(sys.platform != "win32", reason="Windows only")
|
||||
def test_grabclipboard_png(self) -> None:
|
||||
p = subprocess.Popen(["powershell", "-command", "-"], stdin=subprocess.PIPE)
|
||||
assert p.stdin is not None
|
||||
p.stdin.write(
|
||||
rb"""$bytes = [System.IO.File]::ReadAllBytes("Tests\images\hopper.png")
|
||||
$ms = new-object System.IO.MemoryStream(, $bytes)
|
||||
|
@ -113,7 +115,7 @@ $ms = new-object System.IO.MemoryStream(, $bytes)
|
|||
reason="Linux with wl-clipboard only",
|
||||
)
|
||||
@pytest.mark.parametrize("ext", ("gif", "png", "ico"))
|
||||
def test_grabclipboard_wl_clipboard(self, ext) -> None:
|
||||
def test_grabclipboard_wl_clipboard(self, ext: str) -> None:
|
||||
image_path = "Tests/images/hopper." + ext
|
||||
with open(image_path, "rb") as fp:
|
||||
subprocess.call(["wl-copy"], stdin=fp)
|
||||
|
@ -128,6 +130,6 @@ $ms = new-object System.IO.MemoryStream(, $bytes)
|
|||
reason="Linux with wl-clipboard only",
|
||||
)
|
||||
@pytest.mark.parametrize("arg", ("text", "--clear"))
|
||||
def test_grabclipboard_wl_clipboard_errors(self, arg):
|
||||
def test_grabclipboard_wl_clipboard_errors(self, arg: str) -> None:
|
||||
subprocess.call(["wl-copy", arg])
|
||||
assert ImageGrab.grabclipboard() is None
|
||||
|
|
|
@ -58,7 +58,9 @@ def test_path() -> None:
|
|||
ImagePath.Path((0, 1)),
|
||||
),
|
||||
)
|
||||
def test_path_constructors(coords) -> None:
|
||||
def test_path_constructors(
|
||||
coords: Sequence[float] | array.array[float] | ImagePath.Path,
|
||||
) -> None:
|
||||
# Arrange / Act
|
||||
p = ImagePath.Path(coords)
|
||||
|
||||
|
@ -206,9 +208,9 @@ class Evil:
|
|||
def __init__(self) -> None:
|
||||
self.corrupt = Image.core.path(0x4000000000000000)
|
||||
|
||||
def __getitem__(self, i):
|
||||
def __getitem__(self, i: int) -> bytes:
|
||||
x = self.corrupt[i]
|
||||
return struct.pack("dd", x[0], x[1])
|
||||
|
||||
def __setitem__(self, i, x) -> None:
|
||||
def __setitem__(self, i: int, x: bytes) -> None:
|
||||
self.corrupt[i] = struct.unpack("dd", x)
|
||||
|
|
|
@ -28,7 +28,7 @@ def test_rgb() -> None:
|
|||
|
||||
assert qRgb(0, 0, 0) == qRgba(0, 0, 0, 255)
|
||||
|
||||
def checkrgb(r, g, b) -> None:
|
||||
def checkrgb(r: int, g: int, b: int) -> None:
|
||||
val = ImageQt.rgb(r, g, b)
|
||||
val = val % 2**24 # drop the alpha
|
||||
assert val >> 16 == r
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
from PIL import Image, ImageShow
|
||||
|
@ -24,9 +26,9 @@ def test_register() -> None:
|
|||
"order",
|
||||
[-1, 0],
|
||||
)
|
||||
def test_viewer_show(order) -> None:
|
||||
def test_viewer_show(order: int) -> None:
|
||||
class TestViewer(ImageShow.Viewer):
|
||||
def show_image(self, image, **options) -> bool:
|
||||
def show_image(self, image: Image.Image, **options: Any) -> bool:
|
||||
self.methodCalled = True
|
||||
return True
|
||||
|
||||
|
@ -48,7 +50,7 @@ def test_viewer_show(order) -> None:
|
|||
reason="Only run on CIs; hangs on Windows CIs",
|
||||
)
|
||||
@pytest.mark.parametrize("mode", ("1", "I;16", "LA", "RGB", "RGBA"))
|
||||
def test_show(mode) -> None:
|
||||
def test_show(mode: str) -> None:
|
||||
im = hopper(mode)
|
||||
assert ImageShow.show(im)
|
||||
|
||||
|
@ -73,7 +75,7 @@ def test_viewer() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("viewer", ImageShow._viewers)
|
||||
def test_viewers(viewer) -> None:
|
||||
def test_viewers(viewer: ImageShow.Viewer) -> None:
|
||||
try:
|
||||
viewer.get_command("test.jpg")
|
||||
except NotImplementedError:
|
||||
|
|
|
@ -70,7 +70,7 @@ if is_win32():
|
|||
]
|
||||
CreateDIBSection.restype = ctypes.wintypes.HBITMAP
|
||||
|
||||
def serialize_dib(bi, pixels):
|
||||
def serialize_dib(bi, pixels) -> bytearray:
|
||||
bf = BITMAPFILEHEADER()
|
||||
bf.bfType = 0x4D42
|
||||
bf.bfOffBits = ctypes.sizeof(bf) + bi.biSize
|
||||
|
|
|
@ -14,7 +14,7 @@ TEST_IMAGE_SIZE = (10, 10)
|
|||
|
||||
|
||||
def test_numpy_to_image() -> None:
|
||||
def to_image(dtype, bands: int = 1, boolean: int = 0):
|
||||
def to_image(dtype, bands: int = 1, boolean: int = 0) -> Image.Image:
|
||||
if bands == 1:
|
||||
if boolean:
|
||||
data = [0, 255] * 50
|
||||
|
@ -99,7 +99,7 @@ def test_1d_array() -> None:
|
|||
assert_image(Image.fromarray(a), "L", (1, 5))
|
||||
|
||||
|
||||
def _test_img_equals_nparray(img, np) -> None:
|
||||
def _test_img_equals_nparray(img: Image.Image, np) -> None:
|
||||
assert len(np.shape) >= 2
|
||||
np_size = np.shape[1], np.shape[0]
|
||||
assert img.size == np_size
|
||||
|
@ -157,7 +157,7 @@ def test_save_tiff_uint16() -> None:
|
|||
("HSV", numpy.uint8),
|
||||
),
|
||||
)
|
||||
def test_to_array(mode, dtype) -> None:
|
||||
def test_to_array(mode: str, dtype) -> None:
|
||||
img = hopper(mode)
|
||||
|
||||
# Resize to non-square
|
||||
|
|
|
@ -4,7 +4,7 @@ from pathlib import Path
|
|||
|
||||
import pytest
|
||||
|
||||
from PIL import ImageQt
|
||||
from PIL import Image, ImageQt
|
||||
|
||||
from .helper import assert_image_equal_tofile, assert_image_similar, hopper
|
||||
|
||||
|
@ -37,7 +37,7 @@ if ImageQt.qt_is_installed:
|
|||
lbl.setPixmap(pixmap1.copy())
|
||||
|
||||
|
||||
def roundtrip(expected) -> None:
|
||||
def roundtrip(expected: Image.Image) -> None:
|
||||
result = ImageQt.fromqpixmap(ImageQt.toqpixmap(expected))
|
||||
# Qt saves all pixmaps as rgb
|
||||
assert_image_similar(result, expected.convert("RGB"), 1)
|
||||
|
|
|
@ -17,7 +17,7 @@ if ImageQt.qt_is_installed:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("mode", ("RGB", "RGBA", "L", "P", "1"))
|
||||
def test_sanity(mode, tmp_path: Path) -> None:
|
||||
def test_sanity(mode: str, tmp_path: Path) -> None:
|
||||
src = hopper(mode)
|
||||
data = ImageQt.toqimage(src)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ from PIL import _util
|
|||
@pytest.mark.parametrize(
|
||||
"test_path", ["filename.ext", Path("filename.ext"), PurePath("filename.ext")]
|
||||
)
|
||||
def test_is_path(test_path) -> None:
|
||||
def test_is_path(test_path: str | Path | PurePath) -> None:
|
||||
# Act
|
||||
it_is = _util.is_path(test_path)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user