Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.12
rev: v0.12.0
hooks:
- id: ruff-check
args: [--exit-non-zero-on-fix]
Expand All @@ -11,7 +11,7 @@ repos:
- id: black

- repo: https://github.com/PyCQA/bandit
rev: 1.8.3
rev: 1.8.5
hooks:
- id: bandit
args: [--severity-level=high]
Expand All @@ -24,7 +24,7 @@ repos:
exclude: (Makefile$|\.bat$|\.cmake$|\.eps$|\.fits$|\.gd$|\.opt$)

- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v20.1.5
rev: v20.1.6
hooks:
- id: clang-format
types: [c]
Expand All @@ -51,7 +51,7 @@ repos:
exclude: ^.github/.*TEMPLATE|^Tests/(fonts|images)/

- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.33.0
rev: 0.33.1
hooks:
- id: check-github-workflows
- id: check-readthedocs
Expand Down
2 changes: 1 addition & 1 deletion Tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ def _cached_hopper(mode: str) -> Image.Image:
else:
im = hopper()
if mode.startswith("BGR;"):
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="BGR;"):
im = im.convert(mode)
else:
try:
Expand Down
2 changes: 1 addition & 1 deletion Tests/test_core_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,5 @@ def test_units(self) -> None:
),
)
def test_warnings(self, var: dict[str, str]) -> None:
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match=list(var)[0]):
Image._apply_env_variables(var)
13 changes: 6 additions & 7 deletions Tests/test_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_check() -> None:
assert features.check_codec(codec) == features.check(codec)
for feature in features.features:
if "webp" in feature:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="webp"):
assert features.check_feature(feature) == features.check(feature)
else:
assert features.check_feature(feature) == features.check(feature)
Expand Down Expand Up @@ -49,24 +49,24 @@ def test(name: str, function: Callable[[str], str | None]) -> None:
test(codec, features.version_codec)
for feature in features.features:
if "webp" in feature:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="webp"):
test(feature, features.version_feature)
else:
test(feature, features.version_feature)


def test_webp_transparency() -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="transp_webp"):
assert (features.check("transp_webp") or False) == features.check_module("webp")


def test_webp_mux() -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="webp_mux"):
assert (features.check("webp_mux") or False) == features.check_module("webp")


def test_webp_anim() -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="webp_anim"):
assert (features.check("webp_anim") or False) == features.check_module("webp")


Expand Down Expand Up @@ -95,10 +95,9 @@ def test_check_codecs(feature: str) -> None:


def test_check_warns_on_nonexistent() -> None:
with pytest.warns(UserWarning) as cm:
with pytest.warns(UserWarning, match="Unknown feature 'typo'."):
has_feature = features.check("typo")
assert has_feature is False
assert str(cm[-1].message) == "Unknown feature 'typo'."


def test_supported_modules() -> None:
Expand Down
45 changes: 24 additions & 21 deletions Tests/test_file_apng.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,11 @@ def test_apng_chunk_errors() -> None:
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated

with pytest.warns(UserWarning):
with Image.open("Tests/images/apng/chunk_multi_actl.png") as im:
im.load()
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated
with pytest.warns(UserWarning, match="Invalid APNG"):
im = Image.open("Tests/images/apng/chunk_multi_actl.png")
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated
im.close()

with Image.open("Tests/images/apng/chunk_actl_after_idat.png") as im:
assert isinstance(im, PngImagePlugin.PngImageFile)
Expand All @@ -330,18 +330,20 @@ def test_apng_chunk_errors() -> None:


def test_apng_syntax_errors() -> None:
with pytest.warns(UserWarning):
with Image.open("Tests/images/apng/syntax_num_frames_zero.png") as im:
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated
with pytest.raises(OSError):
im.load()
with pytest.warns(UserWarning, match="Invalid APNG"):
im = Image.open("Tests/images/apng/syntax_num_frames_zero.png")
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated
with pytest.raises(OSError):
im.load()
im.close()

with pytest.warns(UserWarning):
with Image.open("Tests/images/apng/syntax_num_frames_zero_default.png") as im:
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated
im.load()
with pytest.warns(UserWarning, match="Invalid APNG"):
im = Image.open("Tests/images/apng/syntax_num_frames_zero_default.png")
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated
im.load()
im.close()

# we can handle this case gracefully
with Image.open("Tests/images/apng/syntax_num_frames_low.png") as im:
Expand All @@ -354,11 +356,12 @@ def test_apng_syntax_errors() -> None:
im.seek(im.n_frames - 1)
im.load()

with pytest.warns(UserWarning):
with Image.open("Tests/images/apng/syntax_num_frames_invalid.png") as im:
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated
im.load()
with pytest.warns(UserWarning, match="Invalid APNG"):
im = Image.open("Tests/images/apng/syntax_num_frames_invalid.png")
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated
im.load()
im.close()


@pytest.mark.parametrize(
Expand Down
4 changes: 2 additions & 2 deletions Tests/test_file_avif.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ class TestUnsupportedAvif:
def test_unsupported(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(AvifImagePlugin, "SUPPORTED", False)

with pytest.warns(UserWarning):
with pytest.raises(UnidentifiedImageError):
with pytest.raises(UnidentifiedImageError):
with pytest.warns(UserWarning, match="AVIF support not installed"):
with Image.open(TEST_AVIF_FILE):
pass

Expand Down
6 changes: 4 additions & 2 deletions Tests/test_file_gif.py
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,9 @@ def test_removed_transparency(tmp_path: Path) -> None:
im.putpixel((x, 0), (x, 0, 0))

im.info["transparency"] = (255, 255, 255)
with pytest.warns(UserWarning):
with pytest.warns(
UserWarning, match="Couldn't allocate palette entry for transparency"
):
im.save(out)

with Image.open(out) as reloaded:
Expand All @@ -1253,7 +1255,7 @@ def test_rgb_transparency(tmp_path: Path) -> None:
im = Image.new("RGB", (1, 1))
im.info["transparency"] = b""
ims = [Image.new("RGB", (1, 1))]
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match="should be converted to RGBA images"):
im.save(out, save_all=True, append_images=ims)

with Image.open(out) as reloaded:
Expand Down
4 changes: 3 additions & 1 deletion Tests/test_file_icns.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ def test_sizes() -> None:
for w, h, r in im.info["sizes"]:
wr = w * r
hr = h * r
with pytest.warns(DeprecationWarning):
with pytest.warns(
DeprecationWarning, match=r"Setting size to \(width, height, scale\)"
):
im.size = (w, h, r)
im.load()
assert im.mode == "RGBA"
Expand Down
2 changes: 1 addition & 1 deletion Tests/test_file_ico.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ def test_save_append_images(tmp_path: Path) -> None:
def test_unexpected_size() -> None:
# This image has been manually hexedited to state that it is 16x32
# while the image within is still 16x16
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match="Image was not the expected size"):
with Image.open("Tests/images/hopper_unexpected.ico") as im:
assert im.size == (16, 16)

Expand Down
6 changes: 3 additions & 3 deletions Tests/test_file_iptc.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def test_i() -> None:
c = b"a"

# Act
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="IptcImagePlugin.i"):
ret = IptcImagePlugin.i(c)

# Assert
Expand All @@ -114,13 +114,13 @@ def test_dump(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(sys, "stdout", mystdout)

# Act
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="IptcImagePlugin.dump"):
IptcImagePlugin.dump(c)

# Assert
assert mystdout.getvalue() == "61 62 63 \n"


def test_pad_deprecation() -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="IptcImagePlugin.PAD"):
assert IptcImagePlugin.PAD == b"\0\0\0\0"
15 changes: 9 additions & 6 deletions Tests/test_file_jpeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,10 +746,13 @@ def test_bad_mpo_header(self) -> None:

# Act
# Shouldn't raise error
fn = "Tests/images/sugarshack_bad_mpo_header.jpg"
with pytest.warns(UserWarning, Image.open, fn) as im:
# Assert
assert im.format == "JPEG"
with pytest.warns(UserWarning, match="malformed MPO file"):
im = Image.open("Tests/images/sugarshack_bad_mpo_header.jpg")

# Assert
assert im.format == "JPEG"

im.close()

@pytest.mark.parametrize("mode", ("1", "L", "RGB", "RGBX", "CMYK", "YCbCr"))
def test_save_correct_modes(self, mode: str) -> None:
Expand Down Expand Up @@ -1097,9 +1100,9 @@ def test_repr_jpeg_error_returns_none(self) -> None:
def test_deprecation(self) -> None:
with Image.open(TEST_FILE) as im:
assert isinstance(im, JpegImagePlugin.JpegImageFile)
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="huffman_ac"):
assert im.huffman_ac == {}
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="huffman_dc"):
assert im.huffman_dc == {}


Expand Down
2 changes: 1 addition & 1 deletion Tests/test_file_png.py
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ def test_deprecation(self, tmp_path: Path) -> None:
test_file = tmp_path / "out.png"

im = hopper("I")
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="Saving I mode images as PNG"):
im.save(test_file)

with Image.open(test_file) as reloaded:
Expand Down
4 changes: 3 additions & 1 deletion Tests/test_file_tga.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ def test_save_id_section(tmp_path: Path) -> None:

# Save with custom id section greater than 255 characters
id_section = b"Test content" * 25
with pytest.warns(UserWarning):
with pytest.warns(
UserWarning, match="id_section has been trimmed to 255 characters"
):
im.save(out, id_section=id_section)

with Image.open(out) as test_im:
Expand Down
4 changes: 2 additions & 2 deletions Tests/test_file_tiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def test_bad_exif(self) -> None:
assert isinstance(im, JpegImagePlugin.JpegImageFile)

# Should not raise struct.error.
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match="Corrupt EXIF data"):
im._getexif()

def test_save_rgba(self, tmp_path: Path) -> None:
Expand Down Expand Up @@ -1014,7 +1014,7 @@ def test_timeout(self, monkeypatch: pytest.MonkeyPatch) -> None:
@timeout_unless_slower_valgrind(2)
def test_oom(self, test_file: str) -> None:
with pytest.raises(UnidentifiedImageError):
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match="Corrupt EXIF data"):
with Image.open(test_file):
pass

Expand Down
4 changes: 2 additions & 2 deletions Tests/test_file_tiff_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def test_empty_metadata() -> None:
head = f.read(8)
info = TiffImagePlugin.ImageFileDirectory(head)
# Should not raise struct.error.
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match="Corrupt EXIF data"):
info.load(f)


Expand Down Expand Up @@ -481,7 +481,7 @@ def test_too_many_entries() -> None:
ifd.tagtype[277] = TiffTags.SHORT

# Should not raise ValueError.
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match="Metadata Warning"):
assert ifd[277] == 4


Expand Down
4 changes: 2 additions & 2 deletions Tests/test_file_webp.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ def test_unsupported(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(WebPImagePlugin, "SUPPORTED", False)

file_path = "Tests/images/hopper.webp"
with pytest.warns(UserWarning):
with pytest.raises(OSError):
with pytest.raises(OSError):
with pytest.warns(UserWarning, match="WEBP support not installed"):
with Image.open(file_path):
pass

Expand Down
12 changes: 6 additions & 6 deletions Tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
# Deprecation helper
def helper_image_new(mode: str, size: tuple[int, int]) -> Image.Image:
if mode.startswith("BGR;"):
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="BGR;"):
return Image.new(mode, size)
else:
return Image.new(mode, size)
Expand Down Expand Up @@ -141,8 +141,8 @@ def test_open_verbose_failure(self, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(Image, "WARN_POSSIBLE_FORMATS", True)

im = io.BytesIO(b"")
with pytest.warns(UserWarning):
with pytest.raises(UnidentifiedImageError):
with pytest.raises(UnidentifiedImageError):
with pytest.warns(UserWarning, match="opening failed"):
with Image.open(im):
pass

Expand Down Expand Up @@ -1008,7 +1008,7 @@ def test_getxmp_padded(self) -> None:

def test_get_child_images(self) -> None:
im = Image.new("RGB", (1, 1))
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="Image.Image.get_child_images"):
assert im.get_child_images() == []

@pytest.mark.parametrize("size", ((1, 0), (0, 1), (0, 0)))
Expand Down Expand Up @@ -1139,7 +1139,7 @@ def test_close_graceful(self, caplog: pytest.LogCaptureFixture) -> None:
assert im.fp is None

def test_deprecation(self) -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="Image.isImageType"):
assert not Image.isImageType(None)


Expand All @@ -1150,7 +1150,7 @@ def test_roundtrip_bytes_constructor(self, mode: str) -> None:
source_bytes = im.tobytes()

if mode.startswith("BGR;"):
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match=mode):
reloaded = Image.frombytes(mode, im.size, source_bytes)
else:
reloaded = Image.frombytes(mode, im.size, source_bytes)
Expand Down
2 changes: 1 addition & 1 deletion Tests/test_image_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def test_basic(self, mode: str) -> None:

@pytest.mark.parametrize("mode", ("BGR;15", "BGR;16", "BGR;24"))
def test_deprecated(self, mode: str) -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="BGR;"):
self.check(mode)

def test_list(self) -> None:
Expand Down
Loading
Loading