mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-01 00:17:27 +03:00 
			
		
		
		
	add _close_exclusive_fp_after_load flag
This commit is contained in:
		
							parent
							
								
									900c5e5bf2
								
							
						
					
					
						commit
						86c1704646
					
				|  | @ -41,6 +41,7 @@ class DcxImageFile(PcxImageFile): | |||
| 
 | ||||
|     format = "DCX" | ||||
|     format_description = "Intel DCX" | ||||
|     _close_exclusive_fp_after_loading = False | ||||
|      | ||||
|     def _open(self): | ||||
| 
 | ||||
|  | @ -58,7 +59,6 @@ class DcxImageFile(PcxImageFile): | |||
|             self._offset.append(offset) | ||||
| 
 | ||||
|         self.__fp = self.fp | ||||
|         self._exclusive_fp = False | ||||
|         self.seek(0) | ||||
| 
 | ||||
|     @property | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ class FliImageFile(ImageFile.ImageFile): | |||
| 
 | ||||
|     format = "FLI" | ||||
|     format_description = "Autodesk FLI/FLC Animation" | ||||
|     _close_exclusive_fp_after_loading = False | ||||
|      | ||||
|     def _open(self): | ||||
| 
 | ||||
|  | @ -84,7 +85,6 @@ class FliImageFile(ImageFile.ImageFile): | |||
|         # set things up to decode first frame | ||||
|         self.__frame = -1 | ||||
|         self.__fp = self.fp | ||||
|         self._exclusive_fp = False | ||||
|         self.__rewind = self.fp.tell() | ||||
|         self._n_frames = None | ||||
|         self._is_animated = None | ||||
|  |  | |||
|  | @ -47,6 +47,8 @@ class GifImageFile(ImageFile.ImageFile): | |||
| 
 | ||||
|     format = "GIF" | ||||
|     format_description = "Compuserve GIF" | ||||
|     _close_exclusive_fp_after_loading = False | ||||
|      | ||||
|     global_palette = None | ||||
| 
 | ||||
|     def data(self): | ||||
|  | @ -80,7 +82,6 @@ class GifImageFile(ImageFile.ImageFile): | |||
|                     break | ||||
| 
 | ||||
|         self.__fp = self.fp  # FIXME: hack | ||||
|         self._exclusive_fp = False | ||||
|         self.__rewind = self.fp.tell() | ||||
|         self._n_frames = None | ||||
|         self._is_animated = None | ||||
|  |  | |||
|  | @ -109,6 +109,7 @@ class ImImageFile(ImageFile.ImageFile): | |||
| 
 | ||||
|     format = "IM" | ||||
|     format_description = "IFUNC Image Memory" | ||||
|     _close_exclusive_fp_after_loading = False | ||||
| 
 | ||||
|     def _open(self): | ||||
| 
 | ||||
|  | @ -234,7 +235,6 @@ class ImImageFile(ImageFile.ImageFile): | |||
|         self.__offset = offs = self.fp.tell() | ||||
| 
 | ||||
|         self.__fp = self.fp  # FIXME: hack | ||||
|         self._exclusive_fp = False | ||||
| 
 | ||||
|         if self.rawmode[:2] == "F;": | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										12
									
								
								PIL/Image.py
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								PIL/Image.py
									
									
									
									
									
								
							|  | @ -506,6 +506,7 @@ class Image(object): | |||
|     """ | ||||
|     format = None | ||||
|     format_description = None | ||||
|     _close_exclusive_fp_after_loading = True | ||||
| 
 | ||||
|     def __init__(self): | ||||
|         # FIXME: take "new" parameters / other image? | ||||
|  | @ -560,6 +561,7 @@ class Image(object): | |||
|         """ | ||||
|         try: | ||||
|             self.fp.close() | ||||
|             self.fp = None | ||||
|         except Exception as msg: | ||||
|             logger.debug("Error closing: %s", msg) | ||||
| 
 | ||||
|  | @ -568,6 +570,13 @@ class Image(object): | |||
|         # object is gone. | ||||
|         self.im = deferred_error(ValueError("Operation on closed image")) | ||||
| 
 | ||||
|     if sys.version_info >= (3,4,0): | ||||
|         def __del__(self): | ||||
|             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): | ||||
|         self.load() | ||||
|         self.im = self.im.copy() | ||||
|  | @ -2440,8 +2449,7 @@ def open(fp, mode="r"): | |||
|             im = _open_core(fp, filename, prefix) | ||||
| 
 | ||||
|     if im: | ||||
|         if getattr(im, '_exclusive_fp', 'undef') is None: | ||||
|             im._exclusive_fp = exclusive_fp | ||||
|         im._exclusive_fp = exclusive_fp | ||||
|         return im | ||||
| 
 | ||||
|     if exclusive_fp: | ||||
|  |  | |||
|  | @ -242,7 +242,9 @@ class ImageFile(Image.Image): | |||
|         self.tile = [] | ||||
|         self.readonly = readonly | ||||
| 
 | ||||
|         if self._exclusive_fp: | ||||
|         self.load_end() | ||||
| 
 | ||||
|         if self._exclusive_fp and self._close_exclusive_fp_after_loading: | ||||
|             self.fp.close() | ||||
|         self.fp = None | ||||
| 
 | ||||
|  | @ -250,8 +252,6 @@ class ImageFile(Image.Image): | |||
|             # still raised if decoder fails to return anything | ||||
|             raise_ioerror(err_code) | ||||
| 
 | ||||
|         self.load_end() | ||||
| 
 | ||||
|         return Image.Image.load(self) | ||||
| 
 | ||||
|     def load_prepare(self): | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ class MicImageFile(TiffImagePlugin.TiffImageFile): | |||
| 
 | ||||
|     format = "MIC" | ||||
|     format_description = "Microsoft Image Composer" | ||||
|     _close_exclusive_fp_after_loading = False | ||||
| 
 | ||||
|     def _open(self): | ||||
| 
 | ||||
|  | @ -64,7 +65,6 @@ class MicImageFile(TiffImagePlugin.TiffImageFile): | |||
|             raise SyntaxError("not an MIC file; no image entries") | ||||
| 
 | ||||
|         self.__fp = self.fp | ||||
|         self._exclusive_fp = False | ||||
|         self.frame = 0 | ||||
| 
 | ||||
|         if len(self.images) > 1: | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile): | |||
| 
 | ||||
|     format = "MPO" | ||||
|     format_description = "MPO (CIPA DC-007)" | ||||
|     _close_exclusive_fp_after_loading = False | ||||
|      | ||||
|     def _open(self): | ||||
|         self.fp.seek(0)  # prep the fp in order to pass the JPEG test | ||||
|  | @ -53,7 +54,6 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile): | |||
|         assert self.__framecount == len(self.__mpoffsets) | ||||
|         del self.info['mpoffset']  # no longer needed | ||||
|         self.__fp = self.fp  # FIXME: hack | ||||
|         self._exclusive_fp = False | ||||
|         self.__fp.seek(self.__mpoffsets[0])  # get ready to read first frame | ||||
|         self.__frame = 0 | ||||
|         self.offset = 0 | ||||
|  |  | |||
|  | @ -97,6 +97,7 @@ class SpiderImageFile(ImageFile.ImageFile): | |||
| 
 | ||||
|     format = "SPIDER" | ||||
|     format_description = "Spider 2D image" | ||||
|     _close_exclusive_fp_after_loading = False | ||||
| 
 | ||||
|     def _open(self): | ||||
|         # check header | ||||
|  | @ -154,7 +155,6 @@ class SpiderImageFile(ImageFile.ImageFile): | |||
|             ("raw", (0, 0) + self.size, offset, | ||||
|                 (self.rawmode, 0, 1))] | ||||
|         self.__fp = self.fp  # FIXME: hack | ||||
|         self._exclusive_fp = False | ||||
| 
 | ||||
|     @property | ||||
|     def n_frames(self): | ||||
|  |  | |||
|  | @ -884,6 +884,7 @@ class TiffImageFile(ImageFile.ImageFile): | |||
| 
 | ||||
|     format = "TIFF" | ||||
|     format_description = "Adobe TIFF" | ||||
|     _close_exclusive_fp_after_loading = False | ||||
| 
 | ||||
|     def _open(self): | ||||
|         "Open the first image in a TIFF file" | ||||
|  | @ -901,7 +902,6 @@ class TiffImageFile(ImageFile.ImageFile): | |||
|         self.__first = self.__next = self.tag_v2.next | ||||
|         self.__frame = -1 | ||||
|         self.__fp = self.fp | ||||
|         self._exclusive_fp = False | ||||
|         self._frame_pos = [] | ||||
|         self._n_frames = None | ||||
|         self._is_animated = None | ||||
|  | @ -1014,7 +1014,7 @@ class TiffImageFile(ImageFile.ImageFile): | |||
|         # allow closing if we're on the first frame, there's no next | ||||
|         # This is the ImageFile.load path only, libtiff specific below. | ||||
|         if self.__frame == 0 and not self.__next: | ||||
|             self._exclusive_fp = True | ||||
|             self._close_exclusive_fp_after_loading = True | ||||
| 
 | ||||
|     def _load_libtiff(self): | ||||
|         """ Overload method triggered when we detect a compressed tiff | ||||
|  | @ -1093,10 +1093,10 @@ class TiffImageFile(ImageFile.ImageFile): | |||
|         self.tile = [] | ||||
|         self.readonly = 0 | ||||
|         # libtiff closed the fp in a, we need to close self.fp, if possible | ||||
|         if hasattr(self.fp, 'close'): | ||||
|         if self._exclusive_fp: | ||||
|             if self.__frame == 0 and not self.__next: | ||||
|                 self.fp.close() | ||||
|         self.fp = None  # might be shared | ||||
|                 self.fp = None  # might be shared | ||||
| 
 | ||||
|         if err < 0: | ||||
|             raise IOError(err) | ||||
|  |  | |||
|  | @ -472,7 +472,6 @@ class TestFileTiff(PillowTestCase): | |||
|     def test_close_on_load(self): | ||||
|         # same as test_fd_leak, but runs on unixlike os | ||||
|         tmpfile = self.tempfile("temp.tif") | ||||
|         import os | ||||
| 
 | ||||
|         with Image.open("Tests/images/uint16_1_4660.tif") as im: | ||||
|             im.save(tmpfile) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user