Skip to content

Commit 58dd4a7

Browse files
authored
Merge pull request #8702 from radarhere/imagefile_fp
2 parents cf7dd2f + c78d23d commit 58dd4a7

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

src/PIL/Image.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -603,24 +603,16 @@ def _new(self, im: core.ImagingCore) -> Image:
603603
def __enter__(self):
604604
return self
605605

606-
def _close_fp(self):
607-
if getattr(self, "_fp", False):
608-
if self._fp != self.fp:
609-
self._fp.close()
610-
self._fp = DeferredError(ValueError("Operation on closed image"))
611-
if self.fp:
612-
self.fp.close()
613-
614606
def __exit__(self, *args):
615-
if hasattr(self, "fp"):
607+
from . import ImageFile
608+
609+
if isinstance(self, ImageFile.ImageFile):
616610
if getattr(self, "_exclusive_fp", False):
617611
self._close_fp()
618612
self.fp = None
619613

620614
def close(self) -> None:
621615
"""
622-
Closes the file pointer, if possible.
623-
624616
This operation will destroy the image core and release its memory.
625617
The image data will be unusable afterward.
626618
@@ -629,13 +621,6 @@ def close(self) -> None:
629621
:py:meth:`~PIL.Image.Image.load` method. See :ref:`file-handling` for
630622
more information.
631623
"""
632-
if hasattr(self, "fp"):
633-
try:
634-
self._close_fp()
635-
self.fp = None
636-
except Exception as msg:
637-
logger.debug("Error closing: %s", msg)
638-
639624
if getattr(self, "map", None):
640625
self.map: mmap.mmap | None = None
641626

src/PIL/ImageFile.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,21 @@
3131
import abc
3232
import io
3333
import itertools
34+
import logging
3435
import os
3536
import struct
3637
import sys
3738
from typing import IO, TYPE_CHECKING, Any, NamedTuple, cast
3839

3940
from . import ExifTags, Image
4041
from ._deprecate import deprecate
41-
from ._util import is_path
42+
from ._util import DeferredError, is_path
4243

4344
if TYPE_CHECKING:
4445
from ._typing import StrOrBytesPath
4546

47+
logger = logging.getLogger(__name__)
48+
4649
MAXBLOCK = 65536
4750

4851
SAFEBLOCK = 1024 * 1024
@@ -163,6 +166,34 @@ def __init__(
163166
def _open(self) -> None:
164167
pass
165168

169+
def _close_fp(self):
170+
if getattr(self, "_fp", False):
171+
if self._fp != self.fp:
172+
self._fp.close()
173+
self._fp = DeferredError(ValueError("Operation on closed image"))
174+
if self.fp:
175+
self.fp.close()
176+
177+
def close(self) -> None:
178+
"""
179+
Closes the file pointer, if possible.
180+
181+
This operation will destroy the image core and release its memory.
182+
The image data will be unusable afterward.
183+
184+
This function is required to close images that have multiple frames or
185+
have not had their file read and closed by the
186+
:py:meth:`~PIL.Image.Image.load` method. See :ref:`file-handling` for
187+
more information.
188+
"""
189+
try:
190+
self._close_fp()
191+
self.fp = None
192+
except Exception as msg:
193+
logger.debug("Error closing: %s", msg)
194+
195+
super().close()
196+
166197
def get_child_images(self) -> list[ImageFile]:
167198
child_images = []
168199
exif = self.getexif()

0 commit comments

Comments
 (0)