Skip to content

Commit d4a740f

Browse files
authored
Merge branch 'main' into path_lists
2 parents 34051b4 + 5f36c9a commit d4a740f

20 files changed

+51
-74
lines changed

Tests/test_file_gif.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ def test_save_dispose(tmp_path: Path) -> None:
601601
Image.new("L", (100, 100), "#111"),
602602
Image.new("L", (100, 100), "#222"),
603603
]
604-
for method in range(0, 4):
604+
for method in range(4):
605605
im_list[0].save(out, save_all=True, append_images=im_list[1:], disposal=method)
606606
with Image.open(out) as img:
607607
for _ in range(2):

Tests/test_file_libtiff.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -1140,11 +1140,9 @@ def test_sampleformat_not_corrupted(self) -> None:
11401140
def test_realloc_overflow(self, monkeypatch: pytest.MonkeyPatch) -> None:
11411141
monkeypatch.setattr(TiffImagePlugin, "READ_LIBTIFF", True)
11421142
with Image.open("Tests/images/tiff_overflow_rows_per_strip.tif") as im:
1143-
with pytest.raises(OSError) as e:
1144-
im.load()
1145-
11461143
# Assert that the error code is IMAGING_CODEC_MEMORY
1147-
assert str(e.value) == "decoder error -9"
1144+
with pytest.raises(OSError, match="decoder error -9"):
1145+
im.load()
11481146

11491147
@pytest.mark.parametrize("compression", ("tiff_adobe_deflate", "jpeg"))
11501148
def test_save_multistrip(self, compression: str, tmp_path: Path) -> None:

Tests/test_file_ppm.py

+5-9
Original file line numberDiff line numberDiff line change
@@ -293,25 +293,21 @@ def test_header_token_too_long(tmp_path: Path) -> None:
293293
with open(path, "wb") as f:
294294
f.write(b"P6\n 01234567890")
295295

296-
with pytest.raises(ValueError) as e:
296+
with pytest.raises(ValueError, match="Token too long in file header: 01234567890"):
297297
with Image.open(path):
298298
pass
299299

300-
assert str(e.value) == "Token too long in file header: 01234567890"
301-
302300

303301
def test_truncated_file(tmp_path: Path) -> None:
304302
# Test EOF in header
305303
path = str(tmp_path / "temp.pgm")
306304
with open(path, "wb") as f:
307305
f.write(b"P6")
308306

309-
with pytest.raises(ValueError) as e:
307+
with pytest.raises(ValueError, match="Reached EOF while reading header"):
310308
with Image.open(path):
311309
pass
312310

313-
assert str(e.value) == "Reached EOF while reading header"
314-
315311
# Test EOF for PyDecoder
316312
fp = BytesIO(b"P5 3 1 4")
317313
with Image.open(fp) as im:
@@ -335,12 +331,12 @@ def test_invalid_maxval(maxval: bytes, tmp_path: Path) -> None:
335331
with open(path, "wb") as f:
336332
f.write(b"P6\n3 1 " + maxval)
337333

338-
with pytest.raises(ValueError) as e:
334+
with pytest.raises(
335+
ValueError, match="maxval must be greater than 0 and less than 65536"
336+
):
339337
with Image.open(path):
340338
pass
341339

342-
assert str(e.value) == "maxval must be greater than 0 and less than 65536"
343-
344340

345341
def test_neg_ppm() -> None:
346342
# Storage.c accepted negative values for xsize, ysize. the

Tests/test_file_tiff.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,8 @@ def test_seek_too_large(self) -> None:
134134

135135
def test_set_legacy_api(self) -> None:
136136
ifd = TiffImagePlugin.ImageFileDirectory_v2()
137-
with pytest.raises(Exception) as e:
137+
with pytest.raises(Exception, match="Not allowing setting of legacy api"):
138138
ifd.legacy_api = False
139-
assert str(e.value) == "Not allowing setting of legacy api"
140139

141140
def test_xyres_tiff(self) -> None:
142141
filename = "Tests/images/pil168.tif"

Tests/test_file_webp.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,8 @@ def test_write_unsupported_mode_P(self, tmp_path: Path) -> None:
154154
@pytest.mark.skipif(sys.maxsize <= 2**32, reason="Requires 64-bit system")
155155
def test_write_encoding_error_message(self, tmp_path: Path) -> None:
156156
im = Image.new("RGB", (15000, 15000))
157-
with pytest.raises(ValueError) as e:
157+
with pytest.raises(ValueError, match="encoding error 6"):
158158
im.save(tmp_path / "temp.webp", method=0)
159-
assert str(e.value) == "encoding error 6"
160159

161160
@pytest.mark.skipif(sys.maxsize <= 2**32, reason="Requires 64-bit system")
162161
def test_write_encoding_error_bad_dimension(self, tmp_path: Path) -> None:
@@ -231,7 +230,7 @@ def test_background_from_gif(self, tmp_path: Path) -> None:
231230

232231
with Image.open(out_gif) as reread:
233232
reread_value = reread.convert("RGB").getpixel((1, 1))
234-
difference = sum(abs(original_value[i] - reread_value[i]) for i in range(0, 3))
233+
difference = sum(abs(original_value[i] - reread_value[i]) for i in range(3))
235234
assert difference < 5
236235

237236
def test_duration(self, tmp_path: Path) -> None:

Tests/test_image.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,8 @@ def test_image_modes_success(self, mode: str) -> None:
6565

6666
@pytest.mark.parametrize("mode", ("", "bad", "very very long"))
6767
def test_image_modes_fail(self, mode: str) -> None:
68-
with pytest.raises(ValueError) as e:
68+
with pytest.raises(ValueError, match="unrecognized image mode"):
6969
Image.new(mode, (1, 1))
70-
assert str(e.value) == "unrecognized image mode"
7170

7271
def test_exception_inheritance(self) -> None:
7372
assert issubclass(UnidentifiedImageError, OSError)

Tests/test_imagedraw.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -1048,8 +1048,8 @@ def create_base_image_draw(
10481048
background2: tuple[int, int, int] = GRAY,
10491049
) -> tuple[Image.Image, ImageDraw.ImageDraw]:
10501050
img = Image.new(mode, size, background1)
1051-
for x in range(0, size[0]):
1052-
for y in range(0, size[1]):
1051+
for x in range(size[0]):
1052+
for y in range(size[1]):
10531053
if (x + y) % 2 == 0:
10541054
img.putpixel((x, y), background2)
10551055
return img, ImageDraw.Draw(img)
@@ -1630,7 +1630,7 @@ def test_compute_regular_polygon_vertices(
16301630
0,
16311631
ValueError,
16321632
"bounding_circle should contain 2D coordinates "
1633-
"and a radius (e.g. (x, y, r) or ((x, y), r) )",
1633+
r"and a radius \(e.g. \(x, y, r\) or \(\(x, y\), r\) \)",
16341634
),
16351635
(
16361636
3,
@@ -1644,7 +1644,7 @@ def test_compute_regular_polygon_vertices(
16441644
((50, 50, 50), 25),
16451645
0,
16461646
ValueError,
1647-
"bounding_circle centre should contain 2D coordinates (e.g. (x, y))",
1647+
r"bounding_circle centre should contain 2D coordinates \(e.g. \(x, y\)\)",
16481648
),
16491649
(
16501650
3,
@@ -1669,9 +1669,8 @@ def test_compute_regular_polygon_vertices_input_error_handling(
16691669
expected_error: type[Exception],
16701670
error_message: str,
16711671
) -> None:
1672-
with pytest.raises(expected_error) as e:
1672+
with pytest.raises(expected_error, match=error_message):
16731673
ImageDraw._compute_regular_polygon_vertices(bounding_circle, n_sides, rotation) # type: ignore[arg-type]
1674-
assert str(e.value) == error_message
16751674

16761675

16771676
def test_continuous_horizontal_edges_polygon() -> None:

Tests/test_imagefile.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,8 @@ def test_truncated(self) -> None:
176176
b"0" * ImageFile.SAFEBLOCK
177177
) # only SAFEBLOCK bytes, so that the header is truncated
178178
)
179-
with pytest.raises(OSError) as e:
179+
with pytest.raises(OSError, match="Truncated File Read"):
180180
BmpImagePlugin.BmpImageFile(b)
181-
assert str(e.value) == "Truncated File Read"
182181

183182
@skip_unless_feature("zlib")
184183
def test_truncated_with_errors(self) -> None:

Tests/test_imagemorph.py

+10-16
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,12 @@ def test_lut(op: str) -> None:
8080
def test_no_operator_loaded() -> None:
8181
im = Image.new("L", (1, 1))
8282
mop = ImageMorph.MorphOp()
83-
with pytest.raises(Exception) as e:
83+
with pytest.raises(Exception, match="No operator loaded"):
8484
mop.apply(im)
85-
assert str(e.value) == "No operator loaded"
86-
with pytest.raises(Exception) as e:
85+
with pytest.raises(Exception, match="No operator loaded"):
8786
mop.match(im)
88-
assert str(e.value) == "No operator loaded"
89-
with pytest.raises(Exception) as e:
87+
with pytest.raises(Exception, match="No operator loaded"):
9088
mop.save_lut("")
91-
assert str(e.value) == "No operator loaded"
9289

9390

9491
# Test the named patterns
@@ -238,15 +235,12 @@ def test_incorrect_mode() -> None:
238235
im = hopper("RGB")
239236
mop = ImageMorph.MorphOp(op_name="erosion8")
240237

241-
with pytest.raises(ValueError) as e:
238+
with pytest.raises(ValueError, match="Image mode must be L"):
242239
mop.apply(im)
243-
assert str(e.value) == "Image mode must be L"
244-
with pytest.raises(ValueError) as e:
240+
with pytest.raises(ValueError, match="Image mode must be L"):
245241
mop.match(im)
246-
assert str(e.value) == "Image mode must be L"
247-
with pytest.raises(ValueError) as e:
242+
with pytest.raises(ValueError, match="Image mode must be L"):
248243
mop.get_on_pixels(im)
249-
assert str(e.value) == "Image mode must be L"
250244

251245

252246
def test_add_patterns() -> None:
@@ -279,9 +273,10 @@ def test_pattern_syntax_error() -> None:
279273
lb.add_patterns(new_patterns)
280274

281275
# Act / Assert
282-
with pytest.raises(Exception) as e:
276+
with pytest.raises(
277+
Exception, match='Syntax error in pattern "a pattern with a syntax error"'
278+
):
283279
lb.build_lut()
284-
assert str(e.value) == 'Syntax error in pattern "a pattern with a syntax error"'
285280

286281

287282
def test_load_invalid_mrl() -> None:
@@ -290,9 +285,8 @@ def test_load_invalid_mrl() -> None:
290285
mop = ImageMorph.MorphOp()
291286

292287
# Act / Assert
293-
with pytest.raises(Exception) as e:
288+
with pytest.raises(Exception, match="Wrong size operator file!"):
294289
mop.load_lut(invalid_mrl)
295-
assert str(e.value) == "Wrong size operator file!"
296290

297291

298292
def test_roundtrip_mrl(tmp_path: Path) -> None:

Tests/test_imagepalette.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def test_make_linear_lut() -> None:
112112
assert isinstance(lut, list)
113113
assert len(lut) == 256
114114
# Check values
115-
for i in range(0, len(lut)):
115+
for i in range(len(lut)):
116116
assert lut[i] == i
117117

118118

Tests/test_imagepath.py

+2-9
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,9 @@ def test_path_constructors(
7070

7171
def test_invalid_path_constructors() -> None:
7272
# Arrange / Act
73-
with pytest.raises(ValueError) as e:
73+
with pytest.raises(ValueError, match="incorrect coordinate type"):
7474
ImagePath.Path(("a", "b"))
7575

76-
# Assert
77-
assert str(e.value) == "incorrect coordinate type"
78-
7976

8077
@pytest.mark.parametrize(
8178
"coords",
@@ -87,13 +84,9 @@ def test_invalid_path_constructors() -> None:
8784
),
8885
)
8986
def test_path_odd_number_of_coordinates(coords: Sequence[int]) -> None:
90-
# Act
91-
with pytest.raises(ValueError) as e:
87+
with pytest.raises(ValueError, match="wrong number of coordinates"):
9288
ImagePath.Path(coords)
9389

94-
# Assert
95-
assert str(e.value) == "wrong number of coordinates"
96-
9790

9891
@pytest.mark.parametrize(
9992
"coords, expected",

Tests/test_imagesequence.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_sanity(tmp_path: Path) -> None:
3232
def test_iterator() -> None:
3333
with Image.open("Tests/images/multipage.tiff") as im:
3434
i = ImageSequence.Iterator(im)
35-
for index in range(0, im.n_frames):
35+
for index in range(im.n_frames):
3636
assert i[index] == next(i)
3737
with pytest.raises(IndexError):
3838
i[index + 1]

Tests/test_pickle.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def helper_pickle_string(protocol: int, test_file: str, mode: str | None) -> Non
6565
("Tests/images/itxt_chunks.png", None),
6666
],
6767
)
68-
@pytest.mark.parametrize("protocol", range(0, pickle.HIGHEST_PROTOCOL + 1))
68+
@pytest.mark.parametrize("protocol", range(pickle.HIGHEST_PROTOCOL + 1))
6969
def test_pickle_image(
7070
tmp_path: Path, test_file: str, test_mode: str | None, protocol: int
7171
) -> None:
@@ -92,7 +92,7 @@ def test_pickle_la_mode_with_palette(tmp_path: Path) -> None:
9292
im = im.convert("PA")
9393

9494
# Act / Assert
95-
for protocol in range(0, pickle.HIGHEST_PROTOCOL + 1):
95+
for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
9696
im._mode = "LA"
9797
with open(filename, "wb") as f:
9898
pickle.dump(im, f, protocol)
@@ -133,7 +133,7 @@ def helper_assert_pickled_font_images(
133133

134134

135135
@skip_unless_feature("freetype2")
136-
@pytest.mark.parametrize("protocol", list(range(0, pickle.HIGHEST_PROTOCOL + 1)))
136+
@pytest.mark.parametrize("protocol", list(range(pickle.HIGHEST_PROTOCOL + 1)))
137137
def test_pickle_font_string(protocol: int) -> None:
138138
# Arrange
139139
font = ImageFont.truetype(FONT_PATH, FONT_SIZE)
@@ -147,7 +147,7 @@ def test_pickle_font_string(protocol: int) -> None:
147147

148148

149149
@skip_unless_feature("freetype2")
150-
@pytest.mark.parametrize("protocol", list(range(0, pickle.HIGHEST_PROTOCOL + 1)))
150+
@pytest.mark.parametrize("protocol", list(range(pickle.HIGHEST_PROTOCOL + 1)))
151151
def test_pickle_font_file(tmp_path: Path, protocol: int) -> None:
152152
# Arrange
153153
font = ImageFont.truetype(FONT_PATH, FONT_SIZE)

pyproject.toml

+2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ lint.select = [
121121
"ISC", # flake8-implicit-str-concat
122122
"LOG", # flake8-logging
123123
"PGH", # pygrep-hooks
124+
"PIE", # flake8-pie
124125
"PT", # flake8-pytest-style
125126
"PYI", # flake8-pyi
126127
"RUF100", # unused noqa (yesqa)
@@ -133,6 +134,7 @@ lint.ignore = [
133134
"E221", # Multiple spaces before operator
134135
"E226", # Missing whitespace around arithmetic operator
135136
"E241", # Multiple spaces after ','
137+
"PIE790", # flake8-pie: unnecessary-placeholder
136138
"PT001", # pytest-fixture-incorrect-parentheses-style
137139
"PT007", # pytest-parametrize-values-wrong-type
138140
"PT011", # pytest-raises-too-broad

src/PIL/IcnsImagePlugin.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ def read_png_or_jpeg2000(
123123
Image._decompression_bomb_check(im.size)
124124
return {"RGBA": im}
125125
elif (
126-
sig.startswith(b"\xff\x4f\xff\x51")
127-
or sig.startswith(b"\x0d\x0a\x87\x0a")
126+
sig.startswith((b"\xff\x4f\xff\x51", b"\x0d\x0a\x87\x0a"))
128127
or sig == b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a"
129128
):
130129
if not enable_jpeg2k:

src/PIL/Image.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,7 @@ def convert_transparency(
10011001
elif len(mode) == 3:
10021002
transparency = tuple(
10031003
convert_transparency(matrix[i * 4 : i * 4 + 4], transparency)
1004-
for i in range(0, len(transparency))
1004+
for i in range(len(transparency))
10051005
)
10061006
new_im.info["transparency"] = transparency
10071007
return new_im
@@ -4003,7 +4003,7 @@ def get_ifd(self, tag: int) -> dict[int, Any]:
40034003
ifd_data = tag_data[ifd_offset:]
40044004

40054005
makernote = {}
4006-
for i in range(0, struct.unpack("<H", ifd_data[:2])[0]):
4006+
for i in range(struct.unpack("<H", ifd_data[:2])[0]):
40074007
ifd_tag, typ, count, data = struct.unpack(
40084008
"<HHL4s", ifd_data[i * 12 + 2 : (i + 1) * 12 + 2]
40094009
)
@@ -4038,7 +4038,7 @@ def get_ifd(self, tag: int) -> dict[int, Any]:
40384038
self._ifds[tag] = dict(self._fixup_dict(makernote))
40394039
elif self.get(0x010F) == "Nintendo":
40404040
makernote = {}
4041-
for i in range(0, struct.unpack(">H", tag_data[:2])[0]):
4041+
for i in range(struct.unpack(">H", tag_data[:2])[0]):
40424042
ifd_tag, typ, count, data = struct.unpack(
40434043
">HHL4s", tag_data[i * 12 + 2 : (i + 1) * 12 + 2]
40444044
)

src/PIL/ImageDraw.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1204,7 +1204,7 @@ def _get_angles(n_sides: int, rotation: float) -> list[float]:
12041204
degrees = 360 / n_sides
12051205
# Start with the bottom left polygon vertex
12061206
current_angle = (270 - 0.5 * degrees) + rotation
1207-
for _ in range(0, n_sides):
1207+
for _ in range(n_sides):
12081208
angles.append(current_angle)
12091209
current_angle += degrees
12101210
if current_angle > 360:
@@ -1227,4 +1227,4 @@ def _color_diff(
12271227
first = color1 if isinstance(color1, tuple) else (color1,)
12281228
second = color2 if isinstance(color2, tuple) else (color2,)
12291229

1230-
return sum(abs(first[i] - second[i]) for i in range(0, len(second)))
1230+
return sum(abs(first[i] - second[i]) for i in range(len(second)))

0 commit comments

Comments
 (0)