Add match parameter to pytest.warns()

This commit is contained in:
Hugo van Kemenade 2025-06-25 16:47:06 +03:00
parent 234875bf90
commit d1894dcd46
28 changed files with 80 additions and 69 deletions

View File

@ -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:

View File

@ -188,5 +188,5 @@ class TestEnvVars:
),
)
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)

View File

@ -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)
@ -49,24 +49,24 @@ def test_version() -> 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")
@ -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:

View File

@ -303,7 +303,7 @@ def test_apng_chunk_errors() -> None:
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match="Invalid APNG"): # noqa: PT031
with Image.open("Tests/images/apng/chunk_multi_actl.png") as im:
im.load()
assert isinstance(im, PngImagePlugin.PngImageFile)
@ -330,14 +330,14 @@ def test_apng_chunk_errors() -> None:
def test_apng_syntax_errors() -> None:
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match="Invalid APNG"): # noqa: PT031
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):
with pytest.warns(UserWarning, match="Invalid APNG"): # noqa: PT031
with Image.open("Tests/images/apng/syntax_num_frames_zero_default.png") as im:
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated
@ -354,7 +354,7 @@ def test_apng_syntax_errors() -> None:
im.seek(im.n_frames - 1)
im.load()
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match="Invalid APNG"): # noqa: PT031
with Image.open("Tests/images/apng/syntax_num_frames_invalid.png") as im:
assert isinstance(im, PngImagePlugin.PngImageFile)
assert not im.is_animated

View File

@ -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

View File

@ -1229,7 +1229,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:
@ -1251,7 +1253,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:

View File

@ -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"

View File

@ -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)

View File

@ -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
@ -114,7 +114,7 @@ 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
@ -122,5 +122,5 @@ def test_dump(monkeypatch: pytest.MonkeyPatch) -> None:
def test_pad_deprecation() -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="IptcImagePlugin.PAD"):
assert IptcImagePlugin.PAD == b"\0\0\0\0"

View File

@ -752,10 +752,11 @@ class TestFileJpeg:
# 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"
@pytest.mark.parametrize("mode", ("1", "L", "RGB", "RGBX", "CMYK", "YCbCr"))
def test_save_correct_modes(self, mode: str) -> None:
@ -1103,9 +1104,9 @@ class TestFileJpeg:
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 == {}

View File

@ -805,7 +805,7 @@ class TestFilePng:
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:

View File

@ -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:

View File

@ -221,7 +221,7 @@ class TestFileTiff:
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:
@ -1014,7 +1014,7 @@ class TestFileTiff:
@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

View File

@ -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)
@ -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

View File

@ -33,8 +33,8 @@ class TestUnsupportedWebp:
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

View File

@ -53,7 +53,7 @@ except ImportError:
# 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)
@ -141,8 +141,8 @@ class TestImage:
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
@ -1008,7 +1008,7 @@ class TestImage:
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)))
@ -1139,7 +1139,7 @@ class TestImage:
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)
@ -1150,7 +1150,7 @@ class TestImageBytes:
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)

View File

@ -193,7 +193,7 @@ class TestImageGetPixel:
@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:

View File

@ -47,7 +47,7 @@ def test_toarray() -> None:
with pytest.raises(OSError):
numpy.array(im_truncated)
else:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="__array_interface__"):
numpy.array(im_truncated)
@ -101,7 +101,7 @@ def test_fromarray_strides_without_tobytes() -> None:
with pytest.raises(ValueError):
wrapped = Wrapper({"shape": (1, 1), "strides": (1, 1)})
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="'mode' parameter"):
Image.fromarray(wrapped, "L")
@ -111,7 +111,7 @@ def test_fromarray_palette() -> None:
a = numpy.array(i)
# Act
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="'mode' parameter"):
out = Image.fromarray(a, "P")
# Assert that the Python and C palettes match

View File

@ -203,7 +203,10 @@ def test_trns_RGB(tmp_path: Path) -> None:
assert "transparency" not in im_rgba.info
assert im_rgba.getpixel((0, 0)) == (0, 0, 0, 0)
im_p = pytest.warns(UserWarning, im.convert, "P", palette=Image.Palette.ADAPTIVE)
with pytest.warns(
UserWarning, match="Couldn't allocate palette entry for transparency"
):
im_p = im.convert("P", palette=Image.Palette.ADAPTIVE)
assert "transparency" not in im_p.info
im_p.save(f)

View File

@ -11,9 +11,9 @@ def test_sanity() -> None:
type_repr = repr(type(im.getim()))
assert "PyCapsule" in type_repr
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="id property"):
assert isinstance(im.im.id, int)
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="unsafe_ptrs property"):
ptrs = dict(im.im.unsafe_ptrs)
assert ptrs.keys() == {"image8", "image32", "image"}

View File

@ -81,7 +81,7 @@ def test_mode_F() -> None:
@pytest.mark.parametrize("mode", ("BGR;15", "BGR;16", "BGR;24"))
def test_mode_BGR(mode: str) -> None:
data = [(16, 32, 49), (32, 32, 98)]
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match=mode):
im = Image.new(mode, (1, 2))
im.putdata(data)

View File

@ -54,7 +54,7 @@ def skip_missing() -> None:
def test_sanity() -> None:
# basic smoke test.
# this mostly follows the cms_test outline.
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="PIL.ImageCms.versions"):
v = ImageCms.versions() # should return four strings
assert v[0] == "1.0.0 pil"
assert list(map(type, v)) == [str, str, str, str]
@ -679,7 +679,7 @@ def test_auxiliary_channels_isolated() -> None:
def test_long_modes() -> None:
p = ImageCms.getOpenProfile("Tests/icc/sGrey-v2-nano.icc")
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="ABCDEFGHI"):
ImageCms.buildTransform(p, p, "ABCDEFGHI", "ABCDEFGHI")
@ -703,15 +703,15 @@ def test_cmyk_lab() -> None:
def test_deprecation() -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="ImageCms.DESCRIPTION"):
assert ImageCms.DESCRIPTION.strip().startswith("pyCMS")
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="ImageCms.VERSION"):
assert ImageCms.VERSION == "1.0.0 pil"
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="ImageCms.FLAGS"):
assert isinstance(ImageCms.FLAGS, dict)
profile = ImageCmsProfile(ImageCms.createProfile("sRGB"))
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="RGBA;16B"):
ImageCms.ImageCmsTransform(profile, profile, "RGBA;16B", "RGB")
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="RGBA;16B"):
ImageCms.ImageCmsTransform(profile, profile, "RGB", "RGBA;16B")

View File

@ -1735,5 +1735,5 @@ def test_incorrectly_ordered_coordinates(xy: tuple[int, int, int, int]) -> None:
def test_getdraw() -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="'hints' parameter"):
ImageDraw.getdraw(None, [])

View File

@ -152,7 +152,7 @@ class TestImageFile:
assert reads.count(im.decodermaxblock) == 1
def test_raise_oserror(self) -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="raise_oserror"):
with pytest.raises(OSError):
ImageFile.raise_oserror(1)

View File

@ -1175,15 +1175,15 @@ def test_oom(test_file: str) -> None:
def test_raqm_missing_warning(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(ImageFont.core, "HAVE_RAQM", False)
with pytest.warns(UserWarning) as record:
with pytest.warns(
UserWarning,
match="Raqm layout was requested, but Raqm is not available. "
"Falling back to basic layout.",
):
font = ImageFont.truetype(
FONT_PATH, FONT_SIZE, layout_engine=ImageFont.Layout.RAQM
)
assert font.layout_engine == ImageFont.Layout.BASIC
assert str(record[-1].message) == (
"Raqm layout was requested, but Raqm is not available. "
"Falling back to basic layout."
)
@pytest.mark.parametrize("size", [-1, 0])
@ -1202,5 +1202,5 @@ def test_freetype_deprecation(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setattr(features, "version_module", fake_version_module)
# Act / Assert
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="FreeType 2.9.0"):
ImageFont.truetype(FONT_PATH, FONT_SIZE)

View File

@ -56,7 +56,7 @@ def test_sanity() -> None:
def test_options_deprecated() -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="ImageMath.lambda_eval options"):
assert ImageMath.lambda_eval(lambda args: 1, images) == 1

View File

@ -36,12 +36,12 @@ def test_sanity() -> None:
def test_eval_deprecated() -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="ImageMath.eval"):
assert ImageMath.eval("1") == 1
def test_options_deprecated() -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="ImageMath.unsafe_eval options"):
assert ImageMath.unsafe_eval("1", images) == 1

View File

@ -362,13 +362,15 @@ class TestLibUnpack:
)
def test_BGR(self) -> None:
with pytest.warns(DeprecationWarning):
with pytest.warns(DeprecationWarning, match="BGR;15"):
self.assert_unpack(
"BGR;15", "BGR;15", 3, (8, 131, 0), (24, 0, 8), (41, 131, 8)
)
with pytest.warns(DeprecationWarning, match="BGR;16"):
self.assert_unpack(
"BGR;16", "BGR;16", 3, (8, 64, 0), (24, 129, 0), (41, 194, 0)
)
with pytest.warns(DeprecationWarning, match="BGR;24"):
self.assert_unpack("BGR;24", "BGR;24", 3, (1, 2, 3), (4, 5, 6), (7, 8, 9))
def test_RGBA(self) -> None: