Close file handle in TiffImagePlugin when image is closed.

This commit is contained in:
Marcus Brinkmann 2016-11-04 17:09:30 +01:00
parent 5aeb0ed972
commit b26391e745
4 changed files with 34 additions and 4 deletions

View File

@ -550,10 +550,6 @@ class Image(object):
had their file read and closed by the
:py:meth:`~PIL.Image.Image.load` method.
"""
try:
self.fp.close()
except Exception as msg:
logger.debug("Error closing: %s", msg)
# Instead of simply setting to None, we're setting up a
# deferred error that will better explain that the core image

View File

@ -117,6 +117,16 @@ class ImageFile(Image.Image):
# directly after open, and closes file when finished.
self.fp = None
def close(self):
if getattr(self, 'map', None):
self.map = None
try:
if self.fp:
self.fp.close()
except Exception as msg:
logger.debug("Error closing: %s", msg)
Image.Image.close(self)
def load(self):
"Load image data based on tile list"

View File

@ -948,6 +948,11 @@ class TiffImageFile(ImageFile.ImageFile):
self.seek(current)
return self._is_animated
def close(self):
if self.__fp:
self.__fp = None
ImageFile.ImageFile.close(self)
def seek(self, frame):
"Select a given frame as current image"
self._seek(max(frame, 0)) # Questionable backwards compatibility.

View File

@ -2,6 +2,7 @@ from __future__ import print_function
import logging
from io import BytesIO
import struct
import sys
from helper import unittest, PillowTestCase, hopper, py3
@ -499,5 +500,23 @@ class TestFileTiff(PillowTestCase):
with Image.open(mp) as im:
self.assertEqual(im.n_frames, 3)
@unittest.skipUnless(sys.platform.startswith('win32'), "Windows only")
class TestFileTiffW32(PillowTestCase):
def test_fd_leak(self):
tmpfile = self.tempfile("temp.tif")
import os
with Image.open("Tests/images/uint16_1_4660.tif") as im:
im.save(tmpfile)
im = Image.open(tmpfile)
im.load()
self.assertRaises(Exception, lambda: os.remove(tmpfile))
im.close()
os.remove(tmpfile)
if __name__ == '__main__':
unittest.main()