Skip to content

Commit a606fd8

Browse files
committed
Run encoder cleanup method after errors as well
1 parent 2f2b48d commit a606fd8

File tree

2 files changed

+35
-26
lines changed

2 files changed

+35
-26
lines changed

Tests/test_imagefile.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ class MockPyEncoder(ImageFile.PyEncoder):
200200
def encode(self, buffer):
201201
return 1, 1, b""
202202

203+
def cleanup(self):
204+
self.cleanup_called = True
205+
203206

204207
xoff, yoff, xsize, ysize = 10, 20, 100, 100
205208

@@ -327,10 +330,12 @@ def test_negsize(self):
327330
im = MockImageFile(buf)
328331

329332
fp = BytesIO()
333+
self.encoder.cleanup_called = False
330334
with pytest.raises(ValueError):
331335
ImageFile._save(
332336
im, fp, [("MOCK", (xoff, yoff, -10, yoff + ysize), 0, "RGB")]
333337
)
338+
assert self.encoder.cleanup_called
334339

335340
with pytest.raises(ValueError):
336341
ImageFile._save(

src/PIL/ImageFile.py

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -503,36 +503,40 @@ def _save(im, fp, tile, bufsize=0):
503503
# compress to Python file-compatible object
504504
for e, b, o, a in tile:
505505
e = Image._getencoder(im.mode, e, a, im.encoderconfig)
506-
if o > 0:
507-
fp.seek(o)
508-
e.setimage(im.im, b)
509-
if e.pushes_fd:
510-
e.setfd(fp)
511-
l, s = e.encode_to_pyfd()
512-
else:
513-
while True:
514-
l, s, d = e.encode(bufsize)
515-
fp.write(d)
516-
if s:
517-
break
518-
if s < 0:
519-
raise OSError(f"encoder error {s} when writing image file") from exc
520-
e.cleanup()
506+
try:
507+
if o > 0:
508+
fp.seek(o)
509+
e.setimage(im.im, b)
510+
if e.pushes_fd:
511+
e.setfd(fp)
512+
l, s = e.encode_to_pyfd()
513+
else:
514+
while True:
515+
l, s, d = e.encode(bufsize)
516+
fp.write(d)
517+
if s:
518+
break
519+
if s < 0:
520+
raise OSError(f"encoder error {s} when writing image file") from exc
521+
finally:
522+
e.cleanup()
521523
else:
522524
# slight speedup: compress to real file object
523525
for e, b, o, a in tile:
524526
e = Image._getencoder(im.mode, e, a, im.encoderconfig)
525-
if o > 0:
526-
fp.seek(o)
527-
e.setimage(im.im, b)
528-
if e.pushes_fd:
529-
e.setfd(fp)
530-
l, s = e.encode_to_pyfd()
531-
else:
532-
s = e.encode_to_file(fh, bufsize)
533-
if s < 0:
534-
raise OSError(f"encoder error {s} when writing image file")
535-
e.cleanup()
527+
try:
528+
if o > 0:
529+
fp.seek(o)
530+
e.setimage(im.im, b)
531+
if e.pushes_fd:
532+
e.setfd(fp)
533+
l, s = e.encode_to_pyfd()
534+
else:
535+
s = e.encode_to_file(fh, bufsize)
536+
if s < 0:
537+
raise OSError(f"encoder error {s} when writing image file")
538+
finally:
539+
e.cleanup()
536540
if hasattr(fp, "flush"):
537541
fp.flush()
538542

0 commit comments

Comments
 (0)