Move fp handling into ImageFile

This commit is contained in:
Eric Soroos 2017-11-13 09:34:37 +00:00
parent af9c0a1cfd
commit 2e94a2e649
2 changed files with 35 additions and 18 deletions

View File

@ -607,28 +607,11 @@ class Image(object):
had their file read and closed by the had their file read and closed by the
:py:meth:`~PIL.Image.Image.load` method. :py:meth:`~PIL.Image.Image.load` method.
""" """
try:
self.fp.close()
self.fp = None
except Exception as msg:
logger.debug("Error closing: %s", msg)
if getattr(self, 'map', None):
self.map = None
# Instead of simply setting to None, we're setting up a # Instead of simply setting to None, we're setting up a
# deferred error that will better explain that the core image # deferred error that will better explain that the core image
# object is gone. # object is gone.
self.im = deferred_error(ValueError("Operation on closed image")) self.im = deferred_error(ValueError("Operation on closed image"))
if sys.version_info >= (3, 4, 0):
def __del__(self):
# type: () -> None
if (hasattr(self, 'fp') and hasattr(self, '_exclusive_fp')
and self.fp and self._exclusive_fp):
self.fp.close()
self.fp = None
def _copy(self): def _copy(self):
# type: () -> None # type: () -> None
self.load() self.load()

View File

@ -33,6 +33,9 @@ import io
import os import os
import sys import sys
import struct import struct
import logging
logger = logging.getLogger(__name__)
MAXBLOCK = 65536 MAXBLOCK = 65536
@ -85,7 +88,8 @@ class ImageFile(Image.Image):
self.decoderconfig = () self.decoderconfig = ()
self.decodermaxblock = MAXBLOCK self.decodermaxblock = MAXBLOCK
self.fp = None # type: Optional[file]
if isPath(fp): if isPath(fp):
# filename # filename
self.fp = open(fp, "rb") self.fp = open(fp, "rb")
@ -113,6 +117,36 @@ class ImageFile(Image.Image):
if not self.mode or self.size[0] <= 0: if not self.mode or self.size[0] <= 0:
raise SyntaxError("not identified by this driver") raise SyntaxError("not identified by this driver")
if sys.version_info >= (3, 4, 0):
def __del__(self):
# type: () -> None
if (hasattr(self, 'fp') and hasattr(self, '_exclusive_fp')
and self.fp and self._exclusive_fp):
self.fp.close()
self.fp = None
def close(self):
"""
Closes the file pointer, if possible.
This operation will destroy the image core and release its memory.
The image data will be unusable afterward.
This function is only required to close images that have not
had their file read and closed by the
:py:meth:`~PIL.Image.Image.load` method.
"""
try:
self.fp.close()
self.fp = None
except Exception as msg:
logger.debug("Error closing: %s", msg)
if getattr(self, 'map', None):
self.map = None
Image.Image.close(self)
def draft(self, mode, size): def draft(self, mode, size):
"Set draft mode" "Set draft mode"