Skip to content

Commit c16737d

Browse files
authored
Merge pull request #6096 from radarhere/cleanup
2 parents fe9b699 + bb9338e commit c16737d

File tree

2 files changed

+30
-32
lines changed

2 files changed

+30
-32
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: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,11 @@ def load(self):
223223
)
224224
]
225225
for decoder_name, extents, offset, args in self.tile:
226+
seek(offset)
226227
decoder = Image._getdecoder(
227228
self.mode, decoder_name, args, self.decoderconfig
228229
)
229230
try:
230-
seek(offset)
231231
decoder.setimage(self.im, extents)
232232
if decoder.pulls_fd:
233233
decoder.setfd(self.fp)
@@ -499,40 +499,33 @@ def _save(im, fp, tile, bufsize=0):
499499
try:
500500
fh = fp.fileno()
501501
fp.flush()
502-
except (AttributeError, io.UnsupportedOperation) as exc:
503-
# compress to Python file-compatible object
504-
for e, b, o, a in tile:
505-
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()
502+
exc = None
503+
except (AttributeError, io.UnsupportedOperation) as e:
504+
exc = e
505+
for e, b, o, a in tile:
506+
if o > 0:
507+
fp.seek(o)
508+
encoder = Image._getencoder(im.mode, e, a, im.encoderconfig)
509+
try:
510+
encoder.setimage(im.im, b)
511+
if encoder.pushes_fd:
512+
encoder.setfd(fp)
513+
l, s = encoder.encode_to_pyfd()
512514
else:
513-
while True:
514-
l, s, d = e.encode(bufsize)
515-
fp.write(d)
516-
if s:
517-
break
515+
if exc:
516+
# compress to Python file-compatible object
517+
while True:
518+
l, s, d = encoder.encode(bufsize)
519+
fp.write(d)
520+
if s:
521+
break
522+
else:
523+
# slight speedup: compress to real file object
524+
s = encoder.encode_to_file(fh, bufsize)
518525
if s < 0:
519526
raise OSError(f"encoder error {s} when writing image file") from exc
520-
e.cleanup()
521-
else:
522-
# slight speedup: compress to real file object
523-
for e, b, o, a in tile:
524-
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+
finally:
528+
encoder.cleanup()
536529
if hasattr(fp, "flush"):
537530
fp.flush()
538531

0 commit comments

Comments
 (0)