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
4a4b90c365
commit
bb1fece57a
|
@ -10,7 +10,7 @@ from .helper import assert_image_similar
|
|||
base = os.path.join("Tests", "images", "bmp")
|
||||
|
||||
|
||||
def get_files(d, ext: str = ".bmp"):
|
||||
def get_files(d: str, ext: str = ".bmp") -> list[str]:
|
||||
return [
|
||||
os.path.join(base, d, f) for f in os.listdir(os.path.join(base, d)) if ext in f
|
||||
]
|
||||
|
@ -29,7 +29,7 @@ def test_bad() -> None:
|
|||
pass
|
||||
|
||||
|
||||
def test_questionable():
|
||||
def test_questionable() -> None:
|
||||
"""These shouldn't crash/dos, but it's not well defined that these
|
||||
are in spec"""
|
||||
supported = [
|
||||
|
@ -80,7 +80,7 @@ def test_good() -> None:
|
|||
"rgb32bf.bmp": "rgb24.png",
|
||||
}
|
||||
|
||||
def get_compare(f):
|
||||
def get_compare(f: str) -> str:
|
||||
name = os.path.split(f)[1]
|
||||
if name in file_map:
|
||||
return os.path.join(base, "html", file_map[name])
|
||||
|
|
|
@ -23,11 +23,11 @@ def test_imageops_box_blur() -> None:
|
|||
assert isinstance(i, Image.Image)
|
||||
|
||||
|
||||
def box_blur(image, radius: int = 1, n: int = 1):
|
||||
def box_blur(image: Image.Image, radius: float = 1, n: int = 1) -> Image.Image:
|
||||
return image._new(image.im.box_blur((radius, radius), n))
|
||||
|
||||
|
||||
def assert_image(im, data, delta: int = 0) -> None:
|
||||
def assert_image(im: Image.Image, data: list[list[int]], delta: int = 0) -> None:
|
||||
it = iter(im.getdata())
|
||||
for data_row in data:
|
||||
im_row = [next(it) for _ in range(im.size[0])]
|
||||
|
@ -37,7 +37,13 @@ def assert_image(im, data, delta: int = 0) -> None:
|
|||
next(it)
|
||||
|
||||
|
||||
def assert_blur(im, radius, data, passes: int = 1, delta: int = 0) -> None:
|
||||
def assert_blur(
|
||||
im: Image.Image,
|
||||
radius: float,
|
||||
data: list[list[int]],
|
||||
passes: int = 1,
|
||||
delta: int = 0,
|
||||
) -> None:
|
||||
# check grayscale image
|
||||
assert_image(box_blur(im, radius, passes), data, delta)
|
||||
rgba = Image.merge("RGBA", (im, im, im, im))
|
||||
|
|
|
@ -47,7 +47,7 @@ def test_apng_basic() -> None:
|
|||
"filename",
|
||||
("Tests/images/apng/split_fdat.png", "Tests/images/apng/split_fdat_zero_chunk.png"),
|
||||
)
|
||||
def test_apng_fdat(filename) -> None:
|
||||
def test_apng_fdat(filename: str) -> None:
|
||||
with Image.open(filename) as im:
|
||||
im.seek(im.n_frames - 1)
|
||||
assert im.getpixel((0, 0)) == (0, 255, 0, 255)
|
||||
|
@ -338,7 +338,7 @@ def test_apng_syntax_errors() -> None:
|
|||
"sequence_fdat_fctl.png",
|
||||
),
|
||||
)
|
||||
def test_apng_sequence_errors(test_file) -> None:
|
||||
def test_apng_sequence_errors(test_file: str) -> None:
|
||||
with pytest.raises(SyntaxError):
|
||||
with Image.open(f"Tests/images/apng/{test_file}") as im:
|
||||
im.seek(im.n_frames - 1)
|
||||
|
@ -681,7 +681,7 @@ def test_seek_after_close() -> None:
|
|||
@pytest.mark.parametrize("default_image", (True, False))
|
||||
@pytest.mark.parametrize("duplicate", (True, False))
|
||||
def test_different_modes_in_later_frames(
|
||||
mode, default_image, duplicate, tmp_path: Path
|
||||
mode: str, default_image: bool, duplicate: bool, tmp_path: Path
|
||||
) -> None:
|
||||
test_file = str(tmp_path / "temp.png")
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ def test_seek_mode_2() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bytesmode", (True, False))
|
||||
def test_read_n0(bytesmode) -> None:
|
||||
def test_read_n0(bytesmode: bool) -> None:
|
||||
# Arrange
|
||||
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
|
@ -80,7 +80,7 @@ def test_read_n0(bytesmode) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bytesmode", (True, False))
|
||||
def test_read_n(bytesmode) -> None:
|
||||
def test_read_n(bytesmode: bool) -> None:
|
||||
# Arrange
|
||||
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
|
@ -96,7 +96,7 @@ def test_read_n(bytesmode) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bytesmode", (True, False))
|
||||
def test_read_eof(bytesmode) -> None:
|
||||
def test_read_eof(bytesmode: bool) -> None:
|
||||
# Arrange
|
||||
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 22, 100)
|
||||
|
@ -112,7 +112,7 @@ def test_read_eof(bytesmode) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bytesmode", (True, False))
|
||||
def test_readline(bytesmode) -> None:
|
||||
def test_readline(bytesmode: bool) -> None:
|
||||
# Arrange
|
||||
with open(TEST_FILE, "rb" if bytesmode else "r") as fh:
|
||||
container = ContainerIO.ContainerIO(fh, 0, 120)
|
||||
|
@ -127,7 +127,7 @@ def test_readline(bytesmode) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bytesmode", (True, False))
|
||||
def test_readlines(bytesmode) -> None:
|
||||
def test_readlines(bytesmode: bool) -> None:
|
||||
# Arrange
|
||||
expected = [
|
||||
"This is line 1\n",
|
||||
|
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||
import warnings
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
from typing import Generator
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -144,13 +145,13 @@ def test_strategy() -> None:
|
|||
|
||||
|
||||
def test_optimize() -> None:
|
||||
def test_grayscale(optimize):
|
||||
def test_grayscale(optimize: int) -> int:
|
||||
im = Image.new("L", (1, 1), 0)
|
||||
filename = BytesIO()
|
||||
im.save(filename, "GIF", optimize=optimize)
|
||||
return len(filename.getvalue())
|
||||
|
||||
def test_bilevel(optimize):
|
||||
def test_bilevel(optimize: int) -> int:
|
||||
im = Image.new("1", (1, 1), 0)
|
||||
test_file = BytesIO()
|
||||
im.save(test_file, "GIF", optimize=optimize)
|
||||
|
@ -178,7 +179,9 @@ def test_optimize() -> None:
|
|||
(4, 513, 256),
|
||||
),
|
||||
)
|
||||
def test_optimize_correctness(colors, size, expected_palette_length) -> None:
|
||||
def test_optimize_correctness(
|
||||
colors: int, size: int, expected_palette_length: int
|
||||
) -> None:
|
||||
# 256 color Palette image, posterize to > 128 and < 128 levels.
|
||||
# Size bigger and smaller than 512x512.
|
||||
# Check the palette for number of colors allocated.
|
||||
|
@ -297,7 +300,7 @@ def test_roundtrip_save_all_1(tmp_path: Path) -> None:
|
|||
("Tests/images/dispose_bgnd_rgba.gif", "RGBA"),
|
||||
),
|
||||
)
|
||||
def test_loading_multiple_palettes(path, mode) -> None:
|
||||
def test_loading_multiple_palettes(path: str, mode: str) -> None:
|
||||
with Image.open(path) as im:
|
||||
assert im.mode == "P"
|
||||
first_frame_colors = im.palette.colors.keys()
|
||||
|
@ -347,9 +350,9 @@ def test_palette_handling(tmp_path: Path) -> None:
|
|||
def test_palette_434(tmp_path: Path) -> None:
|
||||
# see https://github.com/python-pillow/Pillow/issues/434
|
||||
|
||||
def roundtrip(im, *args, **kwargs):
|
||||
def roundtrip(im: Image.Image, **kwargs: bool) -> Image.Image:
|
||||
out = str(tmp_path / "temp.gif")
|
||||
im.copy().save(out, *args, **kwargs)
|
||||
im.copy().save(out, **kwargs)
|
||||
reloaded = Image.open(out)
|
||||
|
||||
return reloaded
|
||||
|
@ -429,7 +432,7 @@ def test_seek_rewind() -> None:
|
|||
("Tests/images/iss634.gif", 42),
|
||||
),
|
||||
)
|
||||
def test_n_frames(path, n_frames) -> None:
|
||||
def test_n_frames(path: str, n_frames: int) -> None:
|
||||
# Test is_animated before n_frames
|
||||
with Image.open(path) as im:
|
||||
assert im.is_animated == (n_frames != 1)
|
||||
|
@ -541,7 +544,10 @@ def test_dispose_background_transparency() -> None:
|
|||
),
|
||||
),
|
||||
)
|
||||
def test_transparent_dispose(loading_strategy, expected_colors) -> None:
|
||||
def test_transparent_dispose(
|
||||
loading_strategy: GifImagePlugin.LoadingStrategy,
|
||||
expected_colors: tuple[tuple[int | tuple[int, int, int, int], ...]],
|
||||
) -> None:
|
||||
GifImagePlugin.LOADING_STRATEGY = loading_strategy
|
||||
try:
|
||||
with Image.open("Tests/images/transparent_dispose.gif") as img:
|
||||
|
@ -889,7 +895,9 @@ def test_identical_frames(tmp_path: Path) -> None:
|
|||
1500,
|
||||
),
|
||||
)
|
||||
def test_identical_frames_to_single_frame(duration, tmp_path: Path) -> None:
|
||||
def test_identical_frames_to_single_frame(
|
||||
duration: int | list[int], tmp_path: Path
|
||||
) -> None:
|
||||
out = str(tmp_path / "temp.gif")
|
||||
im_list = [
|
||||
Image.new("L", (100, 100), "#000"),
|
||||
|
@ -1049,7 +1057,7 @@ def test_retain_comment_in_subsequent_frames(tmp_path: Path) -> None:
|
|||
def test_version(tmp_path: Path) -> None:
|
||||
out = str(tmp_path / "temp.gif")
|
||||
|
||||
def assert_version_after_save(im, version) -> None:
|
||||
def assert_version_after_save(im: Image.Image, version: bytes) -> None:
|
||||
im.save(out)
|
||||
with Image.open(out) as reread:
|
||||
assert reread.info["version"] == version
|
||||
|
@ -1088,7 +1096,7 @@ def test_append_images(tmp_path: Path) -> None:
|
|||
assert reread.n_frames == 3
|
||||
|
||||
# Tests appending using a generator
|
||||
def im_generator(ims):
|
||||
def im_generator(ims: list[Image.Image]) -> Generator[Image.Image, None, None]:
|
||||
yield from ims
|
||||
|
||||
im.save(out, save_all=True, append_images=im_generator(ims))
|
||||
|
|
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
|||
|
||||
import warnings
|
||||
from io import BytesIO
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -19,7 +20,7 @@ test_files = ["Tests/images/sugarshack.mpo", "Tests/images/frozenpond.mpo"]
|
|||
pytestmark = skip_unless_feature("jpg")
|
||||
|
||||
|
||||
def roundtrip(im, **options):
|
||||
def roundtrip(im: Image.Image, **options: Any) -> Image.Image:
|
||||
out = BytesIO()
|
||||
im.save(out, "MPO", **options)
|
||||
test_bytes = out.tell()
|
||||
|
@ -30,7 +31,7 @@ def roundtrip(im, **options):
|
|||
|
||||
|
||||
@pytest.mark.parametrize("test_file", test_files)
|
||||
def test_sanity(test_file) -> None:
|
||||
def test_sanity(test_file: str) -> None:
|
||||
with Image.open(test_file) as im:
|
||||
im.load()
|
||||
assert im.mode == "RGB"
|
||||
|
@ -70,7 +71,7 @@ def test_context_manager() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("test_file", test_files)
|
||||
def test_app(test_file) -> None:
|
||||
def test_app(test_file: str) -> None:
|
||||
# Test APP/COM reader (@PIL135)
|
||||
with Image.open(test_file) as im:
|
||||
assert im.applist[0][0] == "APP1"
|
||||
|
@ -82,7 +83,7 @@ def test_app(test_file) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("test_file", test_files)
|
||||
def test_exif(test_file) -> None:
|
||||
def test_exif(test_file: str) -> None:
|
||||
with Image.open(test_file) as im_original:
|
||||
im_reloaded = roundtrip(im_original, save_all=True, exif=im_original.getexif())
|
||||
|
||||
|
@ -143,7 +144,7 @@ def test_reload_exif_after_seek() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("test_file", test_files)
|
||||
def test_mp(test_file) -> None:
|
||||
def test_mp(test_file: str) -> None:
|
||||
with Image.open(test_file) as im:
|
||||
mpinfo = im._getmp()
|
||||
assert mpinfo[45056] == b"0100"
|
||||
|
@ -168,7 +169,7 @@ def test_mp_no_data() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("test_file", test_files)
|
||||
def test_mp_attribute(test_file) -> None:
|
||||
def test_mp_attribute(test_file: str) -> None:
|
||||
with Image.open(test_file) as im:
|
||||
mpinfo = im._getmp()
|
||||
for frame_number, mpentry in enumerate(mpinfo[0xB002]):
|
||||
|
@ -185,7 +186,7 @@ def test_mp_attribute(test_file) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("test_file", test_files)
|
||||
def test_seek(test_file) -> None:
|
||||
def test_seek(test_file: str) -> None:
|
||||
with Image.open(test_file) as im:
|
||||
assert im.tell() == 0
|
||||
# prior to first image raises an error, both blatant and borderline
|
||||
|
@ -229,7 +230,7 @@ def test_eoferror() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("test_file", test_files)
|
||||
def test_image_grab(test_file) -> None:
|
||||
def test_image_grab(test_file: str) -> None:
|
||||
with Image.open(test_file) as im:
|
||||
assert im.tell() == 0
|
||||
im0 = im.tobytes()
|
||||
|
@ -244,7 +245,7 @@ def test_image_grab(test_file) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("test_file", test_files)
|
||||
def test_save(test_file) -> None:
|
||||
def test_save(test_file: str) -> None:
|
||||
with Image.open(test_file) as im:
|
||||
assert im.tell() == 0
|
||||
jpg0 = roundtrip(im)
|
||||
|
|
|
@ -70,7 +70,9 @@ def test_sanity() -> None:
|
|||
),
|
||||
),
|
||||
)
|
||||
def test_arbitrary_maxval(data, mode, pixels) -> None:
|
||||
def test_arbitrary_maxval(
|
||||
data: bytes, mode: str, pixels: tuple[int | tuple[int, int, int], ...]
|
||||
) -> None:
|
||||
fp = BytesIO(data)
|
||||
with Image.open(fp) as im:
|
||||
assert im.size == (3, 1)
|
||||
|
@ -139,7 +141,7 @@ def test_pfm_big_endian(tmp_path: Path) -> None:
|
|||
b"Pf 1 1 -0.0 \0\0\0\0",
|
||||
],
|
||||
)
|
||||
def test_pfm_invalid(data) -> None:
|
||||
def test_pfm_invalid(data: bytes) -> None:
|
||||
with pytest.raises(ValueError):
|
||||
with Image.open(BytesIO(data)):
|
||||
pass
|
||||
|
@ -162,7 +164,7 @@ def test_pfm_invalid(data) -> None:
|
|||
),
|
||||
),
|
||||
)
|
||||
def test_plain(plain_path, raw_path) -> None:
|
||||
def test_plain(plain_path: str, raw_path: str) -> None:
|
||||
with Image.open(plain_path) as im:
|
||||
assert_image_equal_tofile(im, raw_path)
|
||||
|
||||
|
@ -186,7 +188,9 @@ def test_16bit_plain_pgm() -> None:
|
|||
(b"P3\n2 2\n255", b"0 0 0 001 1 1 2 2 2 255 255 255", 10**6),
|
||||
),
|
||||
)
|
||||
def test_plain_data_with_comment(tmp_path: Path, header, data, comment_count) -> None:
|
||||
def test_plain_data_with_comment(
|
||||
tmp_path: Path, header: bytes, data: bytes, comment_count: int
|
||||
) -> None:
|
||||
path1 = str(tmp_path / "temp1.ppm")
|
||||
path2 = str(tmp_path / "temp2.ppm")
|
||||
comment = b"# comment" * comment_count
|
||||
|
@ -199,7 +203,7 @@ def test_plain_data_with_comment(tmp_path: Path, header, data, comment_count) ->
|
|||
|
||||
|
||||
@pytest.mark.parametrize("data", (b"P1\n128 128\n", b"P3\n128 128\n255\n"))
|
||||
def test_plain_truncated_data(tmp_path: Path, data) -> None:
|
||||
def test_plain_truncated_data(tmp_path: Path, data: bytes) -> None:
|
||||
path = str(tmp_path / "temp.ppm")
|
||||
with open(path, "wb") as f:
|
||||
f.write(data)
|
||||
|
@ -210,7 +214,7 @@ def test_plain_truncated_data(tmp_path: Path, data) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("data", (b"P1\n128 128\n1009", b"P3\n128 128\n255\n100A"))
|
||||
def test_plain_invalid_data(tmp_path: Path, data) -> None:
|
||||
def test_plain_invalid_data(tmp_path: Path, data: bytes) -> None:
|
||||
path = str(tmp_path / "temp.ppm")
|
||||
with open(path, "wb") as f:
|
||||
f.write(data)
|
||||
|
@ -227,7 +231,7 @@ def test_plain_invalid_data(tmp_path: Path, data) -> None:
|
|||
b"P3\n128 128\n255\n012345678910 0", # token too long
|
||||
),
|
||||
)
|
||||
def test_plain_ppm_token_too_long(tmp_path: Path, data) -> None:
|
||||
def test_plain_ppm_token_too_long(tmp_path: Path, data: bytes) -> None:
|
||||
path = str(tmp_path / "temp.ppm")
|
||||
with open(path, "wb") as f:
|
||||
f.write(data)
|
||||
|
@ -313,7 +317,7 @@ def test_not_enough_image_data(tmp_path: Path) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("maxval", (b"0", b"65536"))
|
||||
def test_invalid_maxval(maxval, tmp_path: Path) -> None:
|
||||
def test_invalid_maxval(maxval: bytes, tmp_path: Path) -> None:
|
||||
path = str(tmp_path / "temp.ppm")
|
||||
with open(path, "wb") as f:
|
||||
f.write(b"P6\n3 1 " + maxval)
|
||||
|
@ -351,7 +355,7 @@ def test_mimetypes(tmp_path: Path) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("buffer", (True, False))
|
||||
def test_save_stdout(buffer) -> None:
|
||||
def test_save_stdout(buffer: bool) -> None:
|
||||
old_stdout = sys.stdout
|
||||
|
||||
if buffer:
|
||||
|
|
|
@ -72,7 +72,7 @@ def test_invalid_file() -> None:
|
|||
|
||||
|
||||
def test_write(tmp_path: Path) -> None:
|
||||
def roundtrip(img) -> None:
|
||||
def roundtrip(img: Image.Image) -> None:
|
||||
out = str(tmp_path / "temp.sgi")
|
||||
img.save(out, format="sgi")
|
||||
assert_image_equal_tofile(img, out)
|
||||
|
|
|
@ -8,7 +8,7 @@ from .helper import assert_image_equal, hopper
|
|||
|
||||
|
||||
@pytest.mark.parametrize("data_type", ("bytes", "memoryview"))
|
||||
def test_sanity(data_type) -> None:
|
||||
def test_sanity(data_type: str) -> None:
|
||||
im1 = hopper()
|
||||
|
||||
data = im1.tobytes()
|
||||
|
|
|
@ -26,7 +26,7 @@ def test_close() -> None:
|
|||
im.getpixel((0, 0))
|
||||
|
||||
|
||||
def test_close_after_load(caplog) -> None:
|
||||
def test_close_after_load(caplog: pytest.LogCaptureFixture) -> None:
|
||||
im = Image.open("Tests/images/hopper.gif")
|
||||
im.load()
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
|
|
|
@ -74,7 +74,14 @@ def test_mode_mismatch() -> None:
|
|||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
@pytest.mark.parametrize("start, end", ((0, 180), (0.5, 180.4)))
|
||||
def test_arc(bbox, start, end) -> None:
|
||||
def test_arc(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int],
|
||||
start: float,
|
||||
end: float,
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -87,7 +94,12 @@ def test_arc(bbox, start, end) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_arc_end_le_start(bbox) -> None:
|
||||
def test_arc_end_le_start(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -102,7 +114,12 @@ def test_arc_end_le_start(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_arc_no_loops(bbox) -> None:
|
||||
def test_arc_no_loops(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# No need to go in loops
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
|
@ -118,7 +135,12 @@ def test_arc_no_loops(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_arc_width(bbox) -> None:
|
||||
def test_arc_width(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -131,7 +153,12 @@ def test_arc_width(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_arc_width_pieslice_large(bbox) -> None:
|
||||
def test_arc_width_pieslice_large(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Tests an arc with a large enough width that it is a pieslice
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
|
@ -145,7 +172,12 @@ def test_arc_width_pieslice_large(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_arc_width_fill(bbox) -> None:
|
||||
def test_arc_width_fill(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -158,7 +190,12 @@ def test_arc_width_fill(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_arc_width_non_whole_angle(bbox) -> None:
|
||||
def test_arc_width_non_whole_angle(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -200,7 +237,13 @@ def test_bitmap() -> None:
|
|||
|
||||
@pytest.mark.parametrize("mode", ("RGB", "L"))
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_chord(mode, bbox) -> None:
|
||||
def test_chord(
|
||||
mode: str,
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int],
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new(mode, (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -214,7 +257,12 @@ def test_chord(mode, bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_chord_width(bbox) -> None:
|
||||
def test_chord_width(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -227,7 +275,12 @@ def test_chord_width(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_chord_width_fill(bbox) -> None:
|
||||
def test_chord_width_fill(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -240,7 +293,12 @@ def test_chord_width_fill(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_chord_zero_width(bbox) -> None:
|
||||
def test_chord_zero_width(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -266,7 +324,13 @@ def test_chord_too_fat() -> None:
|
|||
|
||||
@pytest.mark.parametrize("mode", ("RGB", "L"))
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_ellipse(mode, bbox) -> None:
|
||||
def test_ellipse(
|
||||
mode: str,
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int],
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new(mode, (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -280,7 +344,12 @@ def test_ellipse(mode, bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_ellipse_translucent(bbox) -> None:
|
||||
def test_ellipse_translucent(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im, "RGBA")
|
||||
|
@ -317,7 +386,12 @@ def test_ellipse_symmetric() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_ellipse_width(bbox) -> None:
|
||||
def test_ellipse_width(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -342,7 +416,12 @@ def test_ellipse_width_large() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_ellipse_width_fill(bbox) -> None:
|
||||
def test_ellipse_width_fill(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -355,7 +434,12 @@ def test_ellipse_width_fill(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_ellipse_zero_width(bbox) -> None:
|
||||
def test_ellipse_zero_width(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -367,7 +451,7 @@ def test_ellipse_zero_width(bbox) -> None:
|
|||
assert_image_equal_tofile(im, "Tests/images/imagedraw_ellipse_zero_width.png")
|
||||
|
||||
|
||||
def ellipse_various_sizes_helper(filled):
|
||||
def ellipse_various_sizes_helper(filled: bool) -> Image.Image:
|
||||
ellipse_sizes = range(32)
|
||||
image_size = sum(ellipse_sizes) + len(ellipse_sizes) + 1
|
||||
im = Image.new("RGB", (image_size, image_size))
|
||||
|
@ -409,7 +493,12 @@ def test_ellipse_various_sizes_filled() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("points", POINTS)
|
||||
def test_line(points) -> None:
|
||||
def test_line(
|
||||
points: tuple[tuple[int, int], ...]
|
||||
| list[tuple[int, int]]
|
||||
| tuple[int, ...]
|
||||
| list[int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -482,7 +571,14 @@ def test_transform() -> None:
|
|||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
@pytest.mark.parametrize("start, end", ((-92, 46), (-92.2, 46.2)))
|
||||
def test_pieslice(bbox, start, end) -> None:
|
||||
def test_pieslice(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int],
|
||||
start: float,
|
||||
end: float,
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -495,7 +591,12 @@ def test_pieslice(bbox, start, end) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_pieslice_width(bbox) -> None:
|
||||
def test_pieslice_width(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -508,7 +609,12 @@ def test_pieslice_width(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_pieslice_width_fill(bbox) -> None:
|
||||
def test_pieslice_width_fill(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -522,7 +628,12 @@ def test_pieslice_width_fill(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_pieslice_zero_width(bbox) -> None:
|
||||
def test_pieslice_zero_width(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -577,7 +688,12 @@ def test_pieslice_no_spikes() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("points", POINTS)
|
||||
def test_point(points) -> None:
|
||||
def test_point(
|
||||
points: tuple[tuple[int, int], ...]
|
||||
| list[tuple[int, int]]
|
||||
| tuple[int, ...]
|
||||
| list[int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -602,7 +718,12 @@ def test_point_I16() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("points", POINTS)
|
||||
def test_polygon(points) -> None:
|
||||
def test_polygon(
|
||||
points: tuple[tuple[int, int], ...]
|
||||
| list[tuple[int, int]]
|
||||
| tuple[int, ...]
|
||||
| list[int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -616,7 +737,9 @@ def test_polygon(points) -> None:
|
|||
|
||||
@pytest.mark.parametrize("mode", ("RGB", "L"))
|
||||
@pytest.mark.parametrize("kite_points", KITE_POINTS)
|
||||
def test_polygon_kite(mode, kite_points) -> None:
|
||||
def test_polygon_kite(
|
||||
mode: str, kite_points: tuple[tuple[int, int], ...] | list[tuple[int, int]]
|
||||
) -> None:
|
||||
# Test drawing lines of different gradients (dx>dy, dy>dx) and
|
||||
# vertical (dx==0) and horizontal (dy==0) lines
|
||||
# Arrange
|
||||
|
@ -673,7 +796,12 @@ def test_polygon_translucent() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_rectangle(bbox) -> None:
|
||||
def test_rectangle(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -700,7 +828,12 @@ def test_big_rectangle() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_rectangle_width(bbox) -> None:
|
||||
def test_rectangle_width(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -714,7 +847,12 @@ def test_rectangle_width(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_rectangle_width_fill(bbox) -> None:
|
||||
def test_rectangle_width_fill(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -728,7 +866,12 @@ def test_rectangle_width_fill(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_rectangle_zero_width(bbox) -> None:
|
||||
def test_rectangle_zero_width(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -741,7 +884,12 @@ def test_rectangle_zero_width(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_rectangle_I16(bbox) -> None:
|
||||
def test_rectangle_I16(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("I;16", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -754,7 +902,12 @@ def test_rectangle_I16(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_rectangle_translucent_outline(bbox) -> None:
|
||||
def test_rectangle_translucent_outline(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im, "RGBA")
|
||||
|
@ -772,7 +925,11 @@ def test_rectangle_translucent_outline(bbox) -> None:
|
|||
"xy",
|
||||
[(10, 20, 190, 180), ([10, 20], [190, 180]), ((10, 20), (190, 180))],
|
||||
)
|
||||
def test_rounded_rectangle(xy) -> None:
|
||||
def test_rounded_rectangle(
|
||||
xy: tuple[int, int, int, int]
|
||||
| tuple[list[int]]
|
||||
| tuple[tuple[int, int], tuple[int, int]]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (200, 200))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -789,7 +946,7 @@ def test_rounded_rectangle(xy) -> None:
|
|||
@pytest.mark.parametrize("bottom_right", (True, False))
|
||||
@pytest.mark.parametrize("bottom_left", (True, False))
|
||||
def test_rounded_rectangle_corners(
|
||||
top_left, top_right, bottom_right, bottom_left
|
||||
top_left: bool, top_right: bool, bottom_right: bool, bottom_left: bool
|
||||
) -> None:
|
||||
corners = (top_left, top_right, bottom_right, bottom_left)
|
||||
|
||||
|
@ -824,7 +981,9 @@ def test_rounded_rectangle_corners(
|
|||
((10, 20, 190, 181), 85, "height"),
|
||||
],
|
||||
)
|
||||
def test_rounded_rectangle_non_integer_radius(xy, radius, type) -> None:
|
||||
def test_rounded_rectangle_non_integer_radius(
|
||||
xy: tuple[int, int, int, int], radius: float, type: str
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (200, 200))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -840,7 +999,12 @@ def test_rounded_rectangle_non_integer_radius(xy, radius, type) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_rounded_rectangle_zero_radius(bbox) -> None:
|
||||
def test_rounded_rectangle_zero_radius(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -862,7 +1026,9 @@ def test_rounded_rectangle_zero_radius(bbox) -> None:
|
|||
((20, 20, 80, 80), "both"),
|
||||
],
|
||||
)
|
||||
def test_rounded_rectangle_translucent(xy, suffix) -> None:
|
||||
def test_rounded_rectangle_translucent(
|
||||
xy: tuple[int, int, int, int], suffix: str
|
||||
) -> None:
|
||||
# Arrange
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im, "RGBA")
|
||||
|
@ -879,7 +1045,12 @@ def test_rounded_rectangle_translucent(xy, suffix) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_floodfill(bbox) -> None:
|
||||
def test_floodfill(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
red = ImageColor.getrgb("red")
|
||||
|
||||
for mode, value in [("L", 1), ("RGBA", (255, 0, 0, 0)), ("RGB", red)]:
|
||||
|
@ -912,7 +1083,12 @@ def test_floodfill(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_floodfill_border(bbox) -> None:
|
||||
def test_floodfill_border(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# floodfill() is experimental
|
||||
|
||||
# Arrange
|
||||
|
@ -934,7 +1110,12 @@ def test_floodfill_border(bbox) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_floodfill_thresh(bbox) -> None:
|
||||
def test_floodfill_thresh(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# floodfill() is experimental
|
||||
|
||||
# Arrange
|
||||
|
@ -968,8 +1149,11 @@ def test_floodfill_not_negative() -> None:
|
|||
|
||||
|
||||
def create_base_image_draw(
|
||||
size, mode=DEFAULT_MODE, background1=WHITE, background2=GRAY
|
||||
):
|
||||
size: tuple[int, int],
|
||||
mode: str = DEFAULT_MODE,
|
||||
background1: tuple[int, int, int] = WHITE,
|
||||
background2: tuple[int, int, int] = GRAY,
|
||||
) -> tuple[Image.Image, ImageDraw.ImageDraw]:
|
||||
img = Image.new(mode, size, background1)
|
||||
for x in range(0, size[0]):
|
||||
for y in range(0, size[1]):
|
||||
|
@ -1003,7 +1187,7 @@ def test_triangle_right() -> None:
|
|||
"fill, suffix",
|
||||
((BLACK, "width"), (None, "width_no_fill")),
|
||||
)
|
||||
def test_triangle_right_width(fill, suffix) -> None:
|
||||
def test_triangle_right_width(fill: tuple[int, int, int] | None, suffix: str) -> None:
|
||||
img, draw = create_base_image_draw((100, 100))
|
||||
draw.polygon([(15, 25), (85, 25), (50, 60)], fill, WHITE, width=5)
|
||||
assert_image_equal_tofile(
|
||||
|
@ -1235,7 +1419,7 @@ def test_wide_line_larger_than_int() -> None:
|
|||
],
|
||||
],
|
||||
)
|
||||
def test_line_joint(xy) -> None:
|
||||
def test_line_joint(xy: list[tuple[int, int]] | tuple[int, ...] | list[int]) -> None:
|
||||
im = Image.new("RGB", (500, 325))
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
||||
|
@ -1388,7 +1572,12 @@ def test_default_font_size() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("bbox", BBOX)
|
||||
def test_same_color_outline(bbox) -> None:
|
||||
def test_same_color_outline(
|
||||
bbox: tuple[tuple[int, int], tuple[int, int]]
|
||||
| list[tuple[int, int]]
|
||||
| list[int]
|
||||
| tuple[int, int, int, int]
|
||||
) -> None:
|
||||
# Prepare shape
|
||||
x0, y0 = 5, 5
|
||||
x1, y1 = 5, 50
|
||||
|
@ -1402,7 +1591,8 @@ def test_same_color_outline(bbox) -> None:
|
|||
|
||||
# Begin
|
||||
for mode in ["RGB", "L"]:
|
||||
for fill, outline in [["red", None], ["red", "red"], ["red", "#f00"]]:
|
||||
fill = "red"
|
||||
for outline in [None, "red", "#f00"]:
|
||||
for operation, args in {
|
||||
"chord": [bbox, 0, 180],
|
||||
"ellipse": [bbox],
|
||||
|
@ -1417,6 +1607,7 @@ def test_same_color_outline(bbox) -> None:
|
|||
|
||||
# Act
|
||||
draw_method = getattr(draw, operation)
|
||||
assert isinstance(args, list)
|
||||
args += [fill, outline]
|
||||
draw_method(*args)
|
||||
|
||||
|
@ -1434,7 +1625,9 @@ def test_same_color_outline(bbox) -> None:
|
|||
(3, "triangle_width", {"width": 5, "outline": "yellow"}),
|
||||
],
|
||||
)
|
||||
def test_draw_regular_polygon(n_sides, polygon_name, args) -> None:
|
||||
def test_draw_regular_polygon(
|
||||
n_sides: int, polygon_name: str, args: dict[str, int | str]
|
||||
) -> None:
|
||||
im = Image.new("RGBA", size=(W, H), color=(255, 0, 0, 0))
|
||||
filename = f"Tests/images/imagedraw_{polygon_name}.png"
|
||||
draw = ImageDraw.Draw(im)
|
||||
|
@ -1471,7 +1664,9 @@ def test_draw_regular_polygon(n_sides, polygon_name, args) -> None:
|
|||
),
|
||||
],
|
||||
)
|
||||
def test_compute_regular_polygon_vertices(n_sides, expected_vertices) -> None:
|
||||
def test_compute_regular_polygon_vertices(
|
||||
n_sides: int, expected_vertices: list[tuple[float, float]]
|
||||
) -> None:
|
||||
bounding_circle = (W // 2, H // 2, 25)
|
||||
vertices = ImageDraw._compute_regular_polygon_vertices(bounding_circle, n_sides, 0)
|
||||
assert vertices == expected_vertices
|
||||
|
@ -1569,7 +1764,7 @@ def test_polygon2() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("xy", ((1, 1, 0, 1), (1, 1, 1, 0)))
|
||||
def test_incorrectly_ordered_coordinates(xy) -> None:
|
||||
def test_incorrectly_ordered_coordinates(xy: tuple[int, int, int, int]) -> None:
|
||||
im = Image.new("RGB", (W, H))
|
||||
draw = ImageDraw.Draw(im)
|
||||
with pytest.raises(ValueError):
|
||||
|
|
|
@ -57,7 +57,7 @@ def test_kw() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("mode", TK_MODES)
|
||||
def test_photoimage(mode) -> None:
|
||||
def test_photoimage(mode: str) -> None:
|
||||
# test as image:
|
||||
im = hopper(mode)
|
||||
|
||||
|
@ -79,7 +79,7 @@ def test_photoimage_apply_transparency() -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("mode", TK_MODES)
|
||||
def test_photoimage_blank(mode) -> None:
|
||||
def test_photoimage_blank(mode: str) -> None:
|
||||
# test a image using mode/size:
|
||||
im_tk = ImageTk.PhotoImage(mode, (100, 100))
|
||||
|
||||
|
|
|
@ -10,7 +10,13 @@ X = 255
|
|||
|
||||
|
||||
class TestLibPack:
|
||||
def assert_pack(self, mode, rawmode, data, *pixels) -> None:
|
||||
def assert_pack(
|
||||
self,
|
||||
mode: str,
|
||||
rawmode: str,
|
||||
data: int | bytes,
|
||||
*pixels: int | float | tuple[int, ...],
|
||||
) -> None:
|
||||
"""
|
||||
data - either raw bytes with data or just number of bytes in rawmode.
|
||||
"""
|
||||
|
@ -228,7 +234,13 @@ class TestLibPack:
|
|||
|
||||
|
||||
class TestLibUnpack:
|
||||
def assert_unpack(self, mode, rawmode, data, *pixels) -> None:
|
||||
def assert_unpack(
|
||||
self,
|
||||
mode: str,
|
||||
rawmode: str,
|
||||
data: int | bytes,
|
||||
*pixels: int | float | tuple[int, ...],
|
||||
) -> None:
|
||||
"""
|
||||
data - either raw bytes with data or just number of bytes in rawmode.
|
||||
"""
|
||||
|
|
|
@ -11,7 +11,7 @@ from .helper import hopper
|
|||
original = hopper().resize((32, 32)).convert("I")
|
||||
|
||||
|
||||
def verify(im1) -> None:
|
||||
def verify(im1: Image.Image) -> None:
|
||||
im2 = original.copy()
|
||||
assert im1.size == im2.size
|
||||
pix1 = im1.load()
|
||||
|
@ -27,7 +27,7 @@ def verify(im1) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("mode", ("L", "I;16", "I;16B", "I;16L", "I"))
|
||||
def test_basic(tmp_path: Path, mode) -> None:
|
||||
def test_basic(tmp_path: Path, mode: str) -> None:
|
||||
# PIL 1.1 has limited support for 16-bit image data. Check that
|
||||
# create/copy/transform and save works as expected.
|
||||
|
||||
|
@ -78,7 +78,7 @@ def test_basic(tmp_path: Path, mode) -> None:
|
|||
|
||||
|
||||
def test_tobytes() -> None:
|
||||
def tobytes(mode):
|
||||
def tobytes(mode: str) -> Image.Image:
|
||||
return Image.new(mode, (1, 1), 1).tobytes()
|
||||
|
||||
order = 1 if Image._ENDIAN == "<" else -1
|
||||
|
|
Loading…
Reference in New Issue
Block a user