Added type hints

This commit is contained in:
Andrew Murray 2024-02-12 21:06:17 +11:00
parent cdecb3da91
commit 4ce06aac3b
20 changed files with 108 additions and 75 deletions

View File

@ -1,6 +1,7 @@
from __future__ import annotations
from array import array
from types import ModuleType
import pytest
@ -8,6 +9,7 @@ from PIL import Image, ImageFilter
from .helper import assert_image_equal
numpy: ModuleType | None
try:
import numpy
except ImportError:
@ -397,6 +399,7 @@ class TestColorLut3DFilter:
@pytest.mark.skipif(numpy is None, reason="NumPy not installed")
def test_numpy_sources(self) -> None:
assert numpy is not None
table = numpy.ones((5, 6, 7, 3), dtype=numpy.float16)
with pytest.raises(ValueError, match="should have either channels"):
lut = ImageFilter.Color3DLUT((5, 6, 7), table)
@ -430,6 +433,7 @@ class TestColorLut3DFilter:
@pytest.mark.skipif(numpy is None, reason="NumPy not installed")
def test_numpy_formats(self) -> None:
assert numpy is not None
g = Image.linear_gradient("L")
im = Image.merge(
"RGB",

View File

@ -187,6 +187,6 @@ class TestEnvVars:
{"PILLOW_BLOCKS_MAX": "wat"},
),
)
def test_warnings(self, var) -> None:
def test_warnings(self, var: dict[str, str]) -> None:
with pytest.warns(UserWarning):
Image._apply_env_variables(var)

View File

@ -48,7 +48,7 @@ TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA = "Tests/images/uncompressed_rgb.dds"
TEST_FILE_DX10_BC1_TYPELESS,
),
)
def test_sanity_dxt1_bc1(image_path) -> None:
def test_sanity_dxt1_bc1(image_path: str) -> None:
"""Check DXT1 and BC1 images can be opened"""
with Image.open(TEST_FILE_DXT1.replace(".dds", ".png")) as target:
target = target.convert("RGBA")
@ -96,7 +96,7 @@ def test_sanity_dxt5() -> None:
TEST_FILE_BC4U,
),
)
def test_sanity_ati1_bc4u(image_path) -> None:
def test_sanity_ati1_bc4u(image_path: str) -> None:
"""Check ATI1 and BC4U images can be opened"""
with Image.open(image_path) as im:
@ -117,7 +117,7 @@ def test_sanity_ati1_bc4u(image_path) -> None:
TEST_FILE_DX10_BC4_TYPELESS,
),
)
def test_dx10_bc4(image_path) -> None:
def test_dx10_bc4(image_path: str) -> None:
"""Check DX10 BC4 images can be opened"""
with Image.open(image_path) as im:
@ -138,7 +138,7 @@ def test_dx10_bc4(image_path) -> None:
TEST_FILE_BC5U,
),
)
def test_sanity_ati2_bc5u(image_path) -> None:
def test_sanity_ati2_bc5u(image_path: str) -> None:
"""Check ATI2 and BC5U images can be opened"""
with Image.open(image_path) as im:
@ -162,7 +162,7 @@ def test_sanity_ati2_bc5u(image_path) -> None:
(TEST_FILE_BC5S, TEST_FILE_BC5S),
),
)
def test_dx10_bc5(image_path, expected_path) -> None:
def test_dx10_bc5(image_path: str, expected_path: str) -> None:
"""Check DX10 BC5 images can be opened"""
with Image.open(image_path) as im:
@ -176,7 +176,7 @@ def test_dx10_bc5(image_path, expected_path) -> None:
@pytest.mark.parametrize("image_path", (TEST_FILE_BC6H, TEST_FILE_BC6HS))
def test_dx10_bc6h(image_path) -> None:
def test_dx10_bc6h(image_path: str) -> None:
"""Check DX10 BC6H/BC6HS images can be opened"""
with Image.open(image_path) as im:
@ -257,7 +257,7 @@ def test_dx10_r8g8b8a8_unorm_srgb() -> None:
("RGBA", (800, 600), TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA),
],
)
def test_uncompressed(mode, size, test_file) -> None:
def test_uncompressed(mode: str, size: tuple[int, int], test_file: str) -> None:
"""Check uncompressed images can be opened"""
with Image.open(test_file) as im:
@ -359,7 +359,7 @@ def test_unsupported_bitcount() -> None:
"Tests/images/unimplemented_pfflags.dds",
),
)
def test_not_implemented(test_file) -> None:
def test_not_implemented(test_file: str) -> None:
with pytest.raises(NotImplementedError):
with Image.open(test_file):
pass
@ -381,7 +381,7 @@ def test_save_unsupported_mode(tmp_path: Path) -> None:
("RGBA", "Tests/images/pil123rgba.png"),
],
)
def test_save(mode, test_file, tmp_path: Path) -> None:
def test_save(mode: str, test_file: str, tmp_path: Path) -> None:
out = str(tmp_path / "temp.dds")
with Image.open(test_file) as im:
assert im.mode == mode

View File

@ -147,7 +147,7 @@ def test_seek() -> None:
],
)
@pytest.mark.timeout(timeout=3)
def test_timeouts(test_file) -> None:
def test_timeouts(test_file: str) -> None:
with open(test_file, "rb") as f:
with Image.open(f) as im:
with pytest.raises(OSError):
@ -160,7 +160,7 @@ def test_timeouts(test_file) -> None:
"Tests/images/crash-5762152299364352.fli",
],
)
def test_crash(test_file) -> None:
def test_crash(test_file: str) -> None:
with open(test_file, "rb") as f:
with Image.open(f) as im:
with pytest.raises(OSError):

View File

@ -1,6 +1,7 @@
from __future__ import annotations
from pathlib import Path
from typing import IO
import pytest
@ -55,15 +56,15 @@ def test_handler(tmp_path: Path) -> None:
loaded = False
saved = False
def open(self, im) -> None:
def open(self, im: Image.Image) -> None:
self.opened = True
def load(self, im):
def load(self, im: Image.Image) -> Image.Image:
self.loaded = True
im.fp.close()
return Image.new("RGB", (1, 1))
def save(self, im, fp, filename) -> None:
def save(self, im: Image.Image, fp: IO[bytes], filename: str) -> None:
self.saved = True
handler = TestHandler()

View File

@ -1,6 +1,7 @@
from __future__ import annotations
from pathlib import Path
from typing import IO
import pytest
@ -56,15 +57,15 @@ def test_handler(tmp_path: Path) -> None:
loaded = False
saved = False
def open(self, im) -> None:
def open(self, im: Image.Image) -> None:
self.opened = True
def load(self, im):
def load(self, im: Image.Image) -> Image.Image:
self.loaded = True
im.fp.close()
return Image.new("RGB", (1, 1))
def save(self, im, fp, filename) -> None:
def save(self, im: Image.Image, fp: IO[bytes], filename: str) -> None:
self.saved = True
handler = TestHandler()

View File

@ -5,6 +5,7 @@ import re
import warnings
from io import BytesIO
from pathlib import Path
from types import ModuleType
from typing import Any
import pytest
@ -33,6 +34,7 @@ from .helper import (
skip_unless_feature,
)
ElementTree: ModuleType | None
try:
from defusedxml import ElementTree
except ImportError:
@ -440,25 +442,25 @@ class TestFileJpeg:
for subsampling in (-1, 3): # (default, invalid)
im = self.roundtrip(hopper(), subsampling=subsampling)
assert getsampling(im) == (2, 2, 1, 1, 1, 1)
for subsampling in (0, "4:4:4"):
im = self.roundtrip(hopper(), subsampling=subsampling)
for subsampling1 in (0, "4:4:4"):
im = self.roundtrip(hopper(), subsampling=subsampling1)
assert getsampling(im) == (1, 1, 1, 1, 1, 1)
for subsampling in (1, "4:2:2"):
im = self.roundtrip(hopper(), subsampling=subsampling)
for subsampling1 in (1, "4:2:2"):
im = self.roundtrip(hopper(), subsampling=subsampling1)
assert getsampling(im) == (2, 1, 1, 1, 1, 1)
for subsampling in (2, "4:2:0", "4:1:1"):
im = self.roundtrip(hopper(), subsampling=subsampling)
for subsampling1 in (2, "4:2:0", "4:1:1"):
im = self.roundtrip(hopper(), subsampling=subsampling1)
assert getsampling(im) == (2, 2, 1, 1, 1, 1)
# RGB colorspace
for subsampling in (-1, 0, "4:4:4"):
for subsampling1 in (-1, 0, "4:4:4"):
# "4:4:4" doesn't really make sense for RGB, but the conversion
# to an integer happens at a higher level
im = self.roundtrip(hopper(), keep_rgb=True, subsampling=subsampling)
im = self.roundtrip(hopper(), keep_rgb=True, subsampling=subsampling1)
assert getsampling(im) == (1, 1, 1, 1, 1, 1)
for subsampling in (1, "4:2:2", 2, "4:2:0", 3):
for subsampling1 in (1, "4:2:2", 2, "4:2:0", 3):
with pytest.raises(OSError):
self.roundtrip(hopper(), keep_rgb=True, subsampling=subsampling)
self.roundtrip(hopper(), keep_rgb=True, subsampling=subsampling1)
with pytest.raises(TypeError):
self.roundtrip(hopper(), subsampling="1:1:1")

View File

@ -11,7 +11,7 @@ from PIL import Image
from .helper import assert_image_equal, hopper, magick_command
def helper_save_as_palm(tmp_path: Path, mode) -> None:
def helper_save_as_palm(tmp_path: Path, mode: str) -> None:
# Arrange
im = hopper(mode)
outfile = str(tmp_path / ("temp_" + mode + ".palm"))
@ -24,7 +24,7 @@ def helper_save_as_palm(tmp_path: Path, mode) -> None:
assert os.path.getsize(outfile) > 0
def open_with_magick(magick, tmp_path: Path, f):
def open_with_magick(magick: list[str], tmp_path: Path, f: str) -> Image.Image:
outfile = str(tmp_path / "temp.png")
rc = subprocess.call(
magick + [f, outfile], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
@ -33,7 +33,7 @@ def open_with_magick(magick, tmp_path: Path, f):
return Image.open(outfile)
def roundtrip(tmp_path: Path, mode) -> None:
def roundtrip(tmp_path: Path, mode: str) -> None:
magick = magick_command()
if not magick:
return
@ -66,6 +66,6 @@ def test_p_mode(tmp_path: Path) -> None:
@pytest.mark.parametrize("mode", ("L", "RGB"))
def test_oserror(tmp_path: Path, mode) -> None:
def test_oserror(tmp_path: Path, mode: str) -> None:
with pytest.raises(OSError):
helper_save_as_palm(tmp_path, mode)

View File

@ -19,7 +19,7 @@ TEST_TAR_FILE = "Tests/images/hopper.tar"
("jpg", "hopper.jpg", "JPEG"),
),
)
def test_sanity(codec, test_path, format) -> None:
def test_sanity(codec: str, test_path: str, format: str) -> None:
if features.check(codec):
with TarIO.TarIO(TEST_TAR_FILE, test_path) as tar:
with Image.open(tar) as im:

View File

@ -2,6 +2,7 @@ from __future__ import annotations
from io import BytesIO
from pathlib import Path
from types import ModuleType
import pytest
@ -14,6 +15,7 @@ pytestmark = [
skip_unless_feature("webp_mux"),
]
ElementTree: ModuleType | None
try:
from defusedxml import ElementTree
except ImportError:

View File

@ -8,6 +8,7 @@ import sys
import tempfile
import warnings
from pathlib import Path
from typing import IO
import pytest
@ -61,11 +62,11 @@ class TestImage:
"HSV",
),
)
def test_image_modes_success(self, mode) -> None:
def test_image_modes_success(self, mode: str) -> None:
Image.new(mode, (1, 1))
@pytest.mark.parametrize("mode", ("", "bad", "very very long"))
def test_image_modes_fail(self, mode) -> None:
def test_image_modes_fail(self, mode: str) -> None:
with pytest.raises(ValueError) as e:
Image.new(mode, (1, 1))
assert str(e.value) == "unrecognized image mode"
@ -100,7 +101,7 @@ class TestImage:
def test_repr_pretty(self) -> None:
class Pretty:
def text(self, text) -> None:
def text(self, text: str) -> None:
self.pretty_output = text
im = Image.new("L", (100, 100))
@ -184,7 +185,9 @@ class TestImage:
temp_file = str(tmp_path / "temp.jpg")
class FP:
def write(self, b) -> None:
name: str
def write(self, b: bytes) -> None:
pass
fp = FP()
@ -538,7 +541,7 @@ class TestImage:
"PILLOW_VALGRIND_TEST" in os.environ, reason="Valgrind is slower"
)
@pytest.mark.parametrize("size", ((0, 100000000), (100000000, 0)))
def test_empty_image(self, size) -> None:
def test_empty_image(self, size: tuple[int, int]) -> None:
Image.new("RGB", size)
def test_storage_neg(self) -> None:
@ -565,7 +568,7 @@ class TestImage:
Image.linear_gradient(wrong_mode)
@pytest.mark.parametrize("mode", ("L", "P", "I", "F"))
def test_linear_gradient(self, mode) -> None:
def test_linear_gradient(self, mode: str) -> None:
# Arrange
target_file = "Tests/images/linear_gradient.png"
@ -590,7 +593,7 @@ class TestImage:
Image.radial_gradient(wrong_mode)
@pytest.mark.parametrize("mode", ("L", "P", "I", "F"))
def test_radial_gradient(self, mode) -> None:
def test_radial_gradient(self, mode: str) -> None:
# Arrange
target_file = "Tests/images/radial_gradient.png"
@ -665,7 +668,11 @@ class TestImage:
blank_p.palette = None
blank_pa.palette = None
def _make_new(base_image, image, palette_result=None) -> None:
def _make_new(
base_image: Image.Image,
image: Image.Image,
palette_result: ImagePalette.ImagePalette | None = None,
) -> None:
new_image = base_image._new(image.im)
assert new_image.mode == image.mode
assert new_image.size == image.size
@ -713,7 +720,7 @@ class TestImage:
def test_load_on_nonexclusive_multiframe(self) -> None:
with open("Tests/images/frozenpond.mpo", "rb") as fp:
def act(fp) -> None:
def act(fp: IO[bytes]) -> None:
im = Image.open(fp)
im.load()
@ -906,12 +913,12 @@ class TestImage:
assert exif.get_ifd(0xA005)
@pytest.mark.parametrize("size", ((1, 0), (0, 1), (0, 0)))
def test_zero_tobytes(self, size) -> None:
def test_zero_tobytes(self, size: tuple[int, int]) -> None:
im = Image.new("RGB", size)
assert im.tobytes() == b""
@pytest.mark.parametrize("size", ((1, 0), (0, 1), (0, 0)))
def test_zero_frombytes(self, size) -> None:
def test_zero_frombytes(self, size: tuple[int, int]) -> None:
Image.frombytes("RGB", size, b"")
im = Image.new("RGB", size)
@ -996,7 +1003,7 @@ class TestImage:
"01r_00.pcx",
],
)
def test_overrun(self, path) -> None:
def test_overrun(self, path: str) -> None:
"""For overrun completeness, test as:
valgrind pytest -qq Tests/test_image.py::TestImage::test_overrun | grep decode.c
"""
@ -1023,7 +1030,7 @@ class TestImage:
pass
assert not hasattr(im, "fp")
def test_close_graceful(self, caplog) -> None:
def test_close_graceful(self, caplog: pytest.LogCaptureFixture) -> None:
with Image.open("Tests/images/hopper.jpg") as im:
copy = im.copy()
with caplog.at_level(logging.DEBUG):
@ -1034,10 +1041,10 @@ class TestImage:
class MockEncoder:
pass
args: tuple[str, ...]
def mock_encode(*args):
def mock_encode(*args: str) -> MockEncoder:
encoder = MockEncoder()
encoder.args = args
return encoder

View File

@ -208,7 +208,9 @@ def test_language() -> None:
),
ids=("None", "ltr", "rtl2", "rtl", "ttb"),
)
def test_getlength(mode, text, direction, expected) -> None:
def test_getlength(
mode: str, text: str, direction: str | None, expected: float
) -> None:
ttf = ImageFont.truetype(FONT_PATH, FONT_SIZE)
im = Image.new(mode, (1, 1), 0)
d = ImageDraw.Draw(im)
@ -230,7 +232,7 @@ def test_getlength(mode, text, direction, expected) -> None:
("i" + ("\u030C" * 15) + "i", "i" + "\u032C" * 15 + "i", "\u035Cii", "i\u0305i"),
ids=("caron-above", "caron-below", "double-breve", "overline"),
)
def test_getlength_combine(mode, direction, text) -> None:
def test_getlength_combine(mode: str, direction: str, text: str) -> None:
if text == "i\u0305i" and direction == "ttb":
pytest.skip("fails with this font")
@ -250,7 +252,7 @@ def test_getlength_combine(mode, direction, text) -> None:
@pytest.mark.parametrize("anchor", ("lt", "mm", "rb", "sm"))
def test_anchor_ttb(anchor) -> None:
def test_anchor_ttb(anchor: str) -> None:
text = "f"
path = f"Tests/images/test_anchor_ttb_{text}_{anchor}.png"
f = ImageFont.truetype("Tests/fonts/NotoSans-Regular.ttf", 120)
@ -306,7 +308,9 @@ combine_tests = (
@pytest.mark.parametrize(
"name, text, anchor, dir, epsilon", combine_tests, ids=[r[0] for r in combine_tests]
)
def test_combine(name, text, dir, anchor, epsilon) -> None:
def test_combine(
name: str, text: str, dir: str | None, anchor: str | None, epsilon: float
) -> None:
path = f"Tests/images/test_combine_{name}.png"
f = ImageFont.truetype("Tests/fonts/NotoSans-Regular.ttf", 48)
@ -337,7 +341,7 @@ def test_combine(name, text, dir, anchor, epsilon) -> None:
("rm", "right"), # pass with getsize
),
)
def test_combine_multiline(anchor, align) -> None:
def test_combine_multiline(anchor: str, align: str) -> None:
# test that multiline text uses getlength, not getsize or getbbox
path = f"Tests/images/test_combine_multiline_{anchor}_{align}.png"

View File

@ -10,7 +10,7 @@ from PIL import Image, ImageMorph, _imagingmorph
from .helper import assert_image_equal_tofile, hopper
def string_to_img(image_string):
def string_to_img(image_string: str) -> Image.Image:
"""Turn a string image representation into a binary image"""
rows = [s for s in image_string.replace(" ", "").split("\n") if len(s)]
height = len(rows)
@ -38,7 +38,7 @@ A = string_to_img(
)
def img_to_string(im):
def img_to_string(im: Image.Image) -> str:
"""Turn a (small) binary image into a string representation"""
chars = ".1"
width, height = im.size
@ -48,11 +48,11 @@ def img_to_string(im):
)
def img_string_normalize(im):
def img_string_normalize(im: str) -> str:
return img_to_string(string_to_img(im))
def assert_img_equal_img_string(a, b_string) -> None:
def assert_img_equal_img_string(a: Image.Image, b_string: str) -> None:
assert img_to_string(a) == img_string_normalize(b_string)
@ -63,7 +63,7 @@ def test_str_to_img() -> None:
@pytest.mark.parametrize(
"op", ("corner", "dilation4", "dilation8", "erosion4", "erosion8", "edge")
)
def test_lut(op) -> None:
def test_lut(op: str) -> None:
lb = ImageMorph.LutBuilder(op_name=op)
assert lb.get_lut() is None

View File

@ -67,7 +67,7 @@ def test_getcolor_rgba_color_rgb_palette() -> None:
(255, ImagePalette.ImagePalette("RGB", list(range(256)) * 3)),
],
)
def test_getcolor_not_special(index, palette) -> None:
def test_getcolor_not_special(index: int, palette: ImagePalette.ImagePalette) -> None:
im = Image.new("P", (1, 1))
# Do not use transparency index as a new color

View File

@ -13,7 +13,9 @@ FONT_SIZE = 20
FONT_PATH = "Tests/fonts/DejaVuSans/DejaVuSans.ttf"
def helper_pickle_file(tmp_path: Path, pickle, protocol, test_file, mode) -> None:
def helper_pickle_file(
tmp_path: Path, protocol: int, test_file: str, mode: str | None
) -> None:
# Arrange
with Image.open(test_file) as im:
filename = str(tmp_path / "temp.pkl")
@ -30,7 +32,7 @@ def helper_pickle_file(tmp_path: Path, pickle, protocol, test_file, mode) -> Non
assert im == loaded_im
def helper_pickle_string(pickle, protocol, test_file, mode) -> None:
def helper_pickle_string(protocol: int, test_file: str, mode: str | None) -> None:
with Image.open(test_file) as im:
if mode:
im = im.convert(mode)
@ -64,10 +66,12 @@ def helper_pickle_string(pickle, protocol, test_file, mode) -> None:
],
)
@pytest.mark.parametrize("protocol", range(0, pickle.HIGHEST_PROTOCOL + 1))
def test_pickle_image(tmp_path: Path, test_file, test_mode, protocol) -> None:
def test_pickle_image(
tmp_path: Path, test_file: str, test_mode: str | None, protocol: int
) -> None:
# Act / Assert
helper_pickle_string(pickle, protocol, test_file, test_mode)
helper_pickle_file(tmp_path, pickle, protocol, test_file, test_mode)
helper_pickle_string(protocol, test_file, test_mode)
helper_pickle_file(tmp_path, protocol, test_file, test_mode)
def test_pickle_la_mode_with_palette(tmp_path: Path) -> None:
@ -99,7 +103,9 @@ def test_pickle_tell() -> None:
assert unpickled_image.tell() == 0
def helper_assert_pickled_font_images(font1, font2) -> None:
def helper_assert_pickled_font_images(
font1: ImageFont.FreeTypeFont, font2: ImageFont.FreeTypeFont
) -> None:
# Arrange
im1 = Image.new(mode="RGBA", size=(300, 100))
im2 = Image.new(mode="RGBA", size=(300, 100))
@ -117,7 +123,7 @@ def helper_assert_pickled_font_images(font1, font2) -> None:
@skip_unless_feature("freetype2")
@pytest.mark.parametrize("protocol", list(range(0, pickle.HIGHEST_PROTOCOL + 1)))
def test_pickle_font_string(protocol) -> None:
def test_pickle_font_string(protocol: int) -> None:
# Arrange
font = ImageFont.truetype(FONT_PATH, FONT_SIZE)
@ -131,7 +137,7 @@ def test_pickle_font_string(protocol) -> None:
@skip_unless_feature("freetype2")
@pytest.mark.parametrize("protocol", list(range(0, pickle.HIGHEST_PROTOCOL + 1)))
def test_pickle_font_file(tmp_path: Path, protocol) -> None:
def test_pickle_font_file(tmp_path: Path, protocol: int) -> None:
# Arrange
font = ImageFont.truetype(FONT_PATH, FONT_SIZE)
filename = str(tmp_path / "temp.pkl")

View File

@ -10,7 +10,7 @@ import pytest
from PIL import Image, PSDraw
def _create_document(ps) -> None:
def _create_document(ps: PSDraw.PSDraw) -> None:
title = "hopper"
box = (1 * 72, 2 * 72, 7 * 72, 10 * 72) # in points
@ -50,7 +50,7 @@ def test_draw_postscript(tmp_path: Path) -> None:
@pytest.mark.parametrize("buffer", (True, False))
def test_stdout(buffer) -> None:
def test_stdout(buffer: bool) -> None:
# Temporarily redirect stdout
old_stdout = sys.stdout

View File

@ -21,7 +21,7 @@ from PIL import Image
"Tests/images/crash-db8bfa78b19721225425530c5946217720d7df4e.sgi",
],
)
def test_crashes(test_file) -> None:
def test_crashes(test_file: str) -> None:
with open(test_file, "rb") as f:
with Image.open(f) as im:
with pytest.raises(OSError):

View File

@ -2,6 +2,7 @@ from __future__ import annotations
import shutil
from pathlib import Path
from typing import Callable
import pytest
@ -17,7 +18,12 @@ test_filenames = ("temp_';", 'temp_";', "temp_'\"|", "temp_'\"||", "temp_'\"&&")
@pytest.mark.skipif(is_win32(), reason="Requires Unix or macOS")
class TestShellInjection:
def assert_save_filename_check(self, tmp_path: Path, src_img, save_func) -> None:
def assert_save_filename_check(
self,
tmp_path: Path,
src_img: Image.Image,
save_func: Callable[[Image.Image, int, str], None],
) -> None:
for filename in test_filenames:
dest_file = str(tmp_path / filename)
save_func(src_img, 0, dest_file)

View File

@ -42,7 +42,7 @@ from .helper import on_ci
@pytest.mark.filterwarnings("ignore:Possibly corrupt EXIF data")
@pytest.mark.filterwarnings("ignore:Metadata warning")
@pytest.mark.filterwarnings("ignore:Truncated File Read")
def test_tiff_crashes(test_file):
def test_tiff_crashes(test_file: str) -> None:
try:
with Image.open(test_file) as im:
im.load()

View File

@ -53,9 +53,9 @@ def test_nonetype() -> None:
def test_ifd_rational_save(tmp_path: Path) -> None:
methods = (True, False)
if not features.check("libtiff"):
methods = (False,)
methods = [True]
if features.check("libtiff"):
methods.append(False)
for libtiff in methods:
TiffImagePlugin.WRITE_LIBTIFF = libtiff