From 4ff18e03b8a703bbc15a9d19ce253c19f1820b5c Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 18 Jan 2025 20:57:04 +1100 Subject: [PATCH] Moved file pointer handling into ImageFile close --- src/PIL/Image.py | 9 --------- src/PIL/ImageFile.py | 23 +++++++++++++++++++++++ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/PIL/Image.py b/src/PIL/Image.py index e512e6fc7..a0c9ff8eb 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -619,8 +619,6 @@ class Image: def close(self) -> None: """ - Closes the file pointer, if possible. - This operation will destroy the image core and release its memory. The image data will be unusable afterward. @@ -629,13 +627,6 @@ class Image: :py:meth:`~PIL.Image.Image.load` method. See :ref:`file-handling` for more information. """ - if hasattr(self, "fp"): - try: - self._close_fp() - self.fp = None - except Exception as msg: - logger.debug("Error closing: %s", msg) - if getattr(self, "map", None): self.map: mmap.mmap | None = None diff --git a/src/PIL/ImageFile.py b/src/PIL/ImageFile.py index 93fb47874..d716e3b5c 100644 --- a/src/PIL/ImageFile.py +++ b/src/PIL/ImageFile.py @@ -31,6 +31,7 @@ from __future__ import annotations import abc import io import itertools +import logging import os import struct import sys @@ -43,6 +44,8 @@ from ._util import is_path if TYPE_CHECKING: from ._typing import StrOrBytesPath +logger = logging.getLogger(__name__) + MAXBLOCK = 65536 SAFEBLOCK = 1024 * 1024 @@ -163,6 +166,26 @@ class ImageFile(Image.Image): def _open(self) -> None: pass + def close(self) -> None: + """ + 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 required to close images that have multiple frames or + have not had their file read and closed by the + :py:meth:`~PIL.Image.Image.load` method. See :ref:`file-handling` for + more information. + """ + try: + self._close_fp() + self.fp = None + except Exception as msg: + logger.debug("Error closing: %s", msg) + + super().close() + def get_child_images(self) -> list[ImageFile]: child_images = [] exif = self.getexif()