Skip to content

Commit e19a149

Browse files
authored
Use monkeypatch (#8707)
Co-authored-by: Andrew Murray <[email protected]>
1 parent 569b785 commit e19a149

13 files changed

+155
-195
lines changed

Tests/check_png_dos.py

+10-11
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,25 @@
33
import zlib
44
from io import BytesIO
55

6+
import pytest
7+
68
from PIL import Image, ImageFile, PngImagePlugin
79

810
TEST_FILE = "Tests/images/png_decompression_dos.png"
911

1012

11-
def test_ignore_dos_text() -> None:
12-
ImageFile.LOAD_TRUNCATED_IMAGES = True
13+
def test_ignore_dos_text(monkeypatch: pytest.MonkeyPatch) -> None:
14+
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
1315

14-
try:
15-
im = Image.open(TEST_FILE)
16+
with Image.open(TEST_FILE) as im:
1617
im.load()
17-
finally:
18-
ImageFile.LOAD_TRUNCATED_IMAGES = False
1918

20-
assert isinstance(im, PngImagePlugin.PngImageFile)
21-
for s in im.text.values():
22-
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
19+
assert isinstance(im, PngImagePlugin.PngImageFile)
20+
for s in im.text.values():
21+
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
2322

24-
for s in im.info.values():
25-
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
23+
for s in im.info.values():
24+
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
2625

2726

2827
def test_dos_text() -> None:

Tests/test_decompression_bomb.py

+8-11
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,16 @@
1212

1313

1414
class TestDecompressionBomb:
15-
def teardown_method(self) -> None:
16-
Image.MAX_IMAGE_PIXELS = ORIGINAL_LIMIT
17-
1815
def test_no_warning_small_file(self) -> None:
1916
# Implicit assert: no warning.
2017
# A warning would cause a failure.
2118
with Image.open(TEST_FILE):
2219
pass
2320

24-
def test_no_warning_no_limit(self) -> None:
21+
def test_no_warning_no_limit(self, monkeypatch: pytest.MonkeyPatch) -> None:
2522
# Arrange
2623
# Turn limit off
27-
Image.MAX_IMAGE_PIXELS = None
24+
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", None)
2825
assert Image.MAX_IMAGE_PIXELS is None
2926

3027
# Act / Assert
@@ -33,18 +30,18 @@ def test_no_warning_no_limit(self) -> None:
3330
with Image.open(TEST_FILE):
3431
pass
3532

36-
def test_warning(self) -> None:
33+
def test_warning(self, monkeypatch: pytest.MonkeyPatch) -> None:
3734
# Set limit to trigger warning on the test file
38-
Image.MAX_IMAGE_PIXELS = 128 * 128 - 1
35+
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", 128 * 128 - 1)
3936
assert Image.MAX_IMAGE_PIXELS == 128 * 128 - 1
4037

4138
with pytest.warns(Image.DecompressionBombWarning):
4239
with Image.open(TEST_FILE):
4340
pass
4441

45-
def test_exception(self) -> None:
42+
def test_exception(self, monkeypatch: pytest.MonkeyPatch) -> None:
4643
# Set limit to trigger exception on the test file
47-
Image.MAX_IMAGE_PIXELS = 64 * 128 - 1
44+
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", 64 * 128 - 1)
4845
assert Image.MAX_IMAGE_PIXELS == 64 * 128 - 1
4946

5047
with pytest.raises(Image.DecompressionBombError):
@@ -66,9 +63,9 @@ def test_exception_gif_extents(self) -> None:
6663
with pytest.raises(Image.DecompressionBombError):
6764
im.seek(1)
6865

69-
def test_exception_gif_zero_width(self) -> None:
66+
def test_exception_gif_zero_width(self, monkeypatch: pytest.MonkeyPatch) -> None:
7067
# Set limit to trigger exception on the test file
71-
Image.MAX_IMAGE_PIXELS = 4 * 64 * 128
68+
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", 4 * 64 * 128)
7269
assert Image.MAX_IMAGE_PIXELS == 4 * 64 * 128
7370

7471
with pytest.raises(Image.DecompressionBombError):

Tests/test_file_fli.py

+13-16
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,19 @@ def test_sanity() -> None:
3535
assert im.is_animated
3636

3737

38-
def test_prefix_chunk() -> None:
39-
ImageFile.LOAD_TRUNCATED_IMAGES = True
40-
try:
41-
with Image.open(animated_test_file_with_prefix_chunk) as im:
42-
assert im.mode == "P"
43-
assert im.size == (320, 200)
44-
assert im.format == "FLI"
45-
assert im.info["duration"] == 171
46-
assert im.is_animated
47-
48-
palette = im.getpalette()
49-
assert palette[3:6] == [255, 255, 255]
50-
assert palette[381:384] == [204, 204, 12]
51-
assert palette[765:] == [252, 0, 0]
52-
finally:
53-
ImageFile.LOAD_TRUNCATED_IMAGES = False
38+
def test_prefix_chunk(monkeypatch: pytest.MonkeyPatch) -> None:
39+
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
40+
with Image.open(animated_test_file_with_prefix_chunk) as im:
41+
assert im.mode == "P"
42+
assert im.size == (320, 200)
43+
assert im.format == "FLI"
44+
assert im.info["duration"] == 171
45+
assert im.is_animated
46+
47+
palette = im.getpalette()
48+
assert palette[3:6] == [255, 255, 255]
49+
assert palette[381:384] == [204, 204, 12]
50+
assert palette[765:] == [252, 0, 0]
5451

5552

5653
@pytest.mark.skipif(is_pypy(), reason="Requires CPython")

Tests/test_file_gif.py

+47-49
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def test_palette_not_needed_for_second_frame() -> None:
109109
assert_image_similar(im, hopper("L").convert("RGB"), 8)
110110

111111

112-
def test_strategy() -> None:
112+
def test_strategy(monkeypatch: pytest.MonkeyPatch) -> None:
113113
with Image.open("Tests/images/iss634.gif") as im:
114114
expected_rgb_always = im.convert("RGB")
115115

@@ -119,35 +119,36 @@ def test_strategy() -> None:
119119
im.seek(1)
120120
expected_different = im.convert("RGB")
121121

122-
try:
123-
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_ALWAYS
124-
with Image.open("Tests/images/iss634.gif") as im:
125-
assert im.mode == "RGB"
126-
assert_image_equal(im, expected_rgb_always)
122+
monkeypatch.setattr(
123+
GifImagePlugin, "LOADING_STRATEGY", GifImagePlugin.LoadingStrategy.RGB_ALWAYS
124+
)
125+
with Image.open("Tests/images/iss634.gif") as im:
126+
assert im.mode == "RGB"
127+
assert_image_equal(im, expected_rgb_always)
127128

128-
with Image.open("Tests/images/chi.gif") as im:
129-
assert im.mode == "RGBA"
130-
assert_image_equal(im, expected_rgb_always_rgba)
129+
with Image.open("Tests/images/chi.gif") as im:
130+
assert im.mode == "RGBA"
131+
assert_image_equal(im, expected_rgb_always_rgba)
131132

132-
GifImagePlugin.LOADING_STRATEGY = (
133-
GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY
134-
)
135-
# Stay in P mode with only a global palette
136-
with Image.open("Tests/images/chi.gif") as im:
137-
assert im.mode == "P"
133+
monkeypatch.setattr(
134+
GifImagePlugin,
135+
"LOADING_STRATEGY",
136+
GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY,
137+
)
138+
# Stay in P mode with only a global palette
139+
with Image.open("Tests/images/chi.gif") as im:
140+
assert im.mode == "P"
138141

139-
im.seek(1)
140-
assert im.mode == "P"
141-
assert_image_equal(im.convert("RGB"), expected_different)
142+
im.seek(1)
143+
assert im.mode == "P"
144+
assert_image_equal(im.convert("RGB"), expected_different)
142145

143-
# Change to RGB mode when a frame has an individual palette
144-
with Image.open("Tests/images/iss634.gif") as im:
145-
assert im.mode == "P"
146+
# Change to RGB mode when a frame has an individual palette
147+
with Image.open("Tests/images/iss634.gif") as im:
148+
assert im.mode == "P"
146149

147-
im.seek(1)
148-
assert im.mode == "RGB"
149-
finally:
150-
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_FIRST
150+
im.seek(1)
151+
assert im.mode == "RGB"
151152

152153

153154
def test_optimize() -> None:
@@ -555,17 +556,15 @@ def test_dispose_background_transparency() -> None:
555556
def test_transparent_dispose(
556557
loading_strategy: GifImagePlugin.LoadingStrategy,
557558
expected_colors: tuple[tuple[int | tuple[int, int, int, int], ...]],
559+
monkeypatch: pytest.MonkeyPatch,
558560
) -> None:
559-
GifImagePlugin.LOADING_STRATEGY = loading_strategy
560-
try:
561-
with Image.open("Tests/images/transparent_dispose.gif") as img:
562-
for frame in range(3):
563-
img.seek(frame)
564-
for x in range(3):
565-
color = img.getpixel((x, 0))
566-
assert color == expected_colors[frame][x]
567-
finally:
568-
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_FIRST
561+
monkeypatch.setattr(GifImagePlugin, "LOADING_STRATEGY", loading_strategy)
562+
with Image.open("Tests/images/transparent_dispose.gif") as img:
563+
for frame in range(3):
564+
img.seek(frame)
565+
for x in range(3):
566+
color = img.getpixel((x, 0))
567+
assert color == expected_colors[frame][x]
569568

570569

571570
def test_dispose_previous() -> None:
@@ -1398,24 +1397,23 @@ def test_lzw_bits() -> None:
13981397
),
13991398
)
14001399
def test_extents(
1401-
test_file: str, loading_strategy: GifImagePlugin.LoadingStrategy
1400+
test_file: str,
1401+
loading_strategy: GifImagePlugin.LoadingStrategy,
1402+
monkeypatch: pytest.MonkeyPatch,
14021403
) -> None:
1403-
GifImagePlugin.LOADING_STRATEGY = loading_strategy
1404-
try:
1405-
with Image.open("Tests/images/" + test_file) as im:
1406-
assert im.size == (100, 100)
1404+
monkeypatch.setattr(GifImagePlugin, "LOADING_STRATEGY", loading_strategy)
1405+
with Image.open("Tests/images/" + test_file) as im:
1406+
assert im.size == (100, 100)
14071407

1408-
# Check that n_frames does not change the size
1409-
assert im.n_frames == 2
1410-
assert im.size == (100, 100)
1408+
# Check that n_frames does not change the size
1409+
assert im.n_frames == 2
1410+
assert im.size == (100, 100)
14111411

1412-
im.seek(1)
1413-
assert im.size == (150, 150)
1412+
im.seek(1)
1413+
assert im.size == (150, 150)
14141414

1415-
im.load()
1416-
assert im.im.size == (150, 150)
1417-
finally:
1418-
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_FIRST
1415+
im.load()
1416+
assert im.im.size == (150, 150)
14191417

14201418

14211419
def test_missing_background() -> None:

Tests/test_file_ico.py

+11-14
Original file line numberDiff line numberDiff line change
@@ -243,26 +243,23 @@ def test_draw_reloaded(tmp_path: Path) -> None:
243243
assert_image_equal_tofile(im, "Tests/images/hopper_draw.ico")
244244

245245

246-
def test_truncated_mask() -> None:
246+
def test_truncated_mask(monkeypatch: pytest.MonkeyPatch) -> None:
247247
# 1 bpp
248248
with open("Tests/images/hopper_mask.ico", "rb") as fp:
249249
data = fp.read()
250250

251-
ImageFile.LOAD_TRUNCATED_IMAGES = True
251+
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
252252
data = data[:-3]
253253

254-
try:
255-
with Image.open(io.BytesIO(data)) as im:
256-
assert im.mode == "1"
254+
with Image.open(io.BytesIO(data)) as im:
255+
assert im.mode == "1"
257256

258-
# 32 bpp
259-
output = io.BytesIO()
260-
expected = hopper("RGBA")
261-
expected.save(output, "ico", bitmap_format="bmp")
257+
# 32 bpp
258+
output = io.BytesIO()
259+
expected = hopper("RGBA")
260+
expected.save(output, "ico", bitmap_format="bmp")
262261

263-
data = output.getvalue()[:-1]
262+
data = output.getvalue()[:-1]
264263

265-
with Image.open(io.BytesIO(data)) as im:
266-
assert im.mode == "RGB"
267-
finally:
268-
ImageFile.LOAD_TRUNCATED_IMAGES = False
264+
with Image.open(io.BytesIO(data)) as im:
265+
assert im.mode == "RGB"

Tests/test_file_jpeg.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -530,12 +530,13 @@ def test_ff00_jpeg_header(self) -> None:
530530
@mark_if_feature_version(
531531
pytest.mark.valgrind_known_error, "libjpeg_turbo", "2.0", reason="Known Failing"
532532
)
533-
def test_truncated_jpeg_should_read_all_the_data(self) -> None:
533+
def test_truncated_jpeg_should_read_all_the_data(
534+
self, monkeypatch: pytest.MonkeyPatch
535+
) -> None:
534536
filename = "Tests/images/truncated_jpeg.jpg"
535-
ImageFile.LOAD_TRUNCATED_IMAGES = True
537+
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
536538
with Image.open(filename) as im:
537539
im.load()
538-
ImageFile.LOAD_TRUNCATED_IMAGES = False
539540
assert im.getbbox() is not None
540541

541542
def test_truncated_jpeg_throws_oserror(self) -> None:
@@ -1024,7 +1025,7 @@ def test_save_xmp(self, tmp_path: Path) -> None:
10241025
im.save(f, xmp=b"1" * 65505)
10251026

10261027
@pytest.mark.timeout(timeout=1)
1027-
def test_eof(self) -> None:
1028+
def test_eof(self, monkeypatch: pytest.MonkeyPatch) -> None:
10281029
# Even though this decoder never says that it is finished
10291030
# the image should still end when there is no new data
10301031
class InfiniteMockPyDecoder(ImageFile.PyDecoder):
@@ -1039,9 +1040,8 @@ def decode(
10391040
im.tile = [
10401041
ImageFile._Tile("INFINITE", (0, 0, 128, 128), 0, ("RGB", 0, 1)),
10411042
]
1042-
ImageFile.LOAD_TRUNCATED_IMAGES = True
1043+
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
10431044
im.load()
1044-
ImageFile.LOAD_TRUNCATED_IMAGES = False
10451045

10461046
def test_separate_tables(self) -> None:
10471047
im = hopper()

Tests/test_file_jpeg2k.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,11 @@ def test_load_dpi() -> None:
181181
assert "dpi" not in im.info
182182

183183

184-
def test_restricted_icc_profile() -> None:
185-
ImageFile.LOAD_TRUNCATED_IMAGES = True
186-
try:
187-
# JPEG2000 image with a restricted ICC profile and a known colorspace
188-
with Image.open("Tests/images/balloon_eciRGBv2_aware.jp2") as im:
189-
assert im.mode == "RGB"
190-
finally:
191-
ImageFile.LOAD_TRUNCATED_IMAGES = False
184+
def test_restricted_icc_profile(monkeypatch: pytest.MonkeyPatch) -> None:
185+
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
186+
# JPEG2000 image with a restricted ICC profile and a known colorspace
187+
with Image.open("Tests/images/balloon_eciRGBv2_aware.jp2") as im:
188+
assert im.mode == "RGB"
192189

193190

194191
@pytest.mark.skipif(

Tests/test_file_libtiff.py

+12-13
Original file line numberDiff line numberDiff line change
@@ -1156,23 +1156,22 @@ def test_save_multistrip(self, compression: str, tmp_path: Path) -> None:
11561156
assert len(im.tag_v2[STRIPOFFSETS]) > 1
11571157

11581158
@pytest.mark.parametrize("argument", (True, False))
1159-
def test_save_single_strip(self, argument: bool, tmp_path: Path) -> None:
1159+
def test_save_single_strip(
1160+
self, argument: bool, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
1161+
) -> None:
11601162
im = hopper("RGB").resize((256, 256))
11611163
out = str(tmp_path / "temp.tif")
11621164

11631165
if not argument:
1164-
TiffImagePlugin.STRIP_SIZE = 2**18
1165-
try:
1166-
arguments: dict[str, str | int] = {"compression": "tiff_adobe_deflate"}
1167-
if argument:
1168-
arguments["strip_size"] = 2**18
1169-
im.save(out, "TIFF", **arguments)
1170-
1171-
with Image.open(out) as im:
1172-
assert isinstance(im, TiffImagePlugin.TiffImageFile)
1173-
assert len(im.tag_v2[STRIPOFFSETS]) == 1
1174-
finally:
1175-
TiffImagePlugin.STRIP_SIZE = 65536
1166+
monkeypatch.setattr(TiffImagePlugin, "STRIP_SIZE", 2**18)
1167+
arguments: dict[str, str | int] = {"compression": "tiff_adobe_deflate"}
1168+
if argument:
1169+
arguments["strip_size"] = 2**18
1170+
im.save(out, "TIFF", **arguments)
1171+
1172+
with Image.open(out) as im:
1173+
assert isinstance(im, TiffImagePlugin.TiffImageFile)
1174+
assert len(im.tag_v2[STRIPOFFSETS]) == 1
11761175

11771176
@pytest.mark.parametrize("compression", ("tiff_adobe_deflate", None))
11781177
def test_save_zero(self, compression: str | None, tmp_path: Path) -> None:

0 commit comments

Comments
 (0)