Merge pull request #3490 from radarhere/open_files

Updated open files documentation
This commit is contained in:
Hugo 2018-12-13 21:14:22 +02:00 committed by GitHub
commit 69837baba2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 29 deletions

View File

@ -4,7 +4,7 @@ File Handling in Pillow
=======================
When opening a file as an image, Pillow requires a filename,
pathlib.Path object, or a file-like object. Pillow uses the filename
pathlib.Path object, or a file-like object. Pillow uses the filename
or Path to open a file, so for the rest of this article, they will all
be treated as a file-like object.
@ -30,10 +30,10 @@ and may fail::
im5 = Image.open(f)
im5.load() # FAILS, closed file
The documentation specifies that the file will be closed after the
``Image.Image.load()`` method is called. This is an aspirational
specification rather than an accurate reflection of the state of the
code.
If a filename or a path-like object is passed to Pillow, then the resulting
file object opened by Pillow may also be closed by Pillow after the
``Image.Image.load()`` method is called, provided the associated image does not
have multiple frames.
Pillow cannot in general close and reopen a file, so any access to
that file needs to be prior to the close.
@ -41,12 +41,6 @@ that file needs to be prior to the close.
Issues
------
The current open file handling is inconsistent at best:
* Most of the image plugins do not close the input file.
* Multi-frame images behave badly when seeking through the file, as
it's legal to seek backward in the file until the last image is
read, and then it's not.
* Using the file context manager to provide a file-like object to
Pillow is dangerous unless the context of the image is limited to
the context of the file.
@ -54,20 +48,20 @@ The current open file handling is inconsistent at best:
Image Lifecycle
---------------
* ``Image.open()`` called. Path-like objects are opened as a
file. Metadata is read from the open file. The file is left open for
further usage.
* ``Image.open()`` Path-like objects are opened as a file. Metadata is read
from the open file. The file is left open for further usage.
* ``Image.Image.load()`` when the pixel data from the image is
* ``Image.Image.load()`` When the pixel data from the image is
required, ``load()`` is called. The current frame is read into
memory. The image can now be used independently of the underlying
image file.
* ``Image.Image.seek()`` in the case of multi-frame images
(e.g. multipage TIFF and animated GIF) the image file left open so
that seek can load the appropriate frame. When the last frame is
read, the image file is closed (at least in some image plugins), and
no more seeks can occur.
If a filename or a path-like object was passed to ``Image.open()``, then
the file object was opened by Pillow and is considered to be used exclusively
by Pillow. So if the image is a single-frame image, the file will
be closed in this method after the frame is read. If the image is a
multi-frame image, (e.g. multipage TIFF and animated GIF) the image file is
left open so that ``Image.Image.seek()`` can load the appropriate frame.
* ``Image.Image.close()`` Closes the file pointer and destroys the
core image object. This is used in the Pillow context manager
@ -77,16 +71,13 @@ Image Lifecycle
... # image operations here.
The lifecycle of a single frame image is relatively simple. The file
The lifecycle of a single-frame image is relatively simple. The file
must remain open until the ``load()`` or ``close()`` function is
called.
Multi-frame images are more complicated. The ``load()`` method is not
a terminal method, so it should not close the underlying file. The
current behavior of ``seek()`` closing the underlying file on
accessing the last frame is presumably a heuristic for closing the
file after iterating through the entire sequence. In general, Pillow
does not know if there are going to be any requests for additional
a terminal method, so it should not close the underlying file. In general,
Pillow does not know if there are going to be any requests for additional
data until the caller has explicitly closed the image.
@ -124,4 +115,3 @@ Proposed File Handling
* Users of the library should call ``Image.Image.close()`` on any
multi-frame image to ensure that the underlying file is closed.

View File

@ -827,8 +827,10 @@ class Image(object):
Image class automatically loads an opened image when it is
accessed for the first time.
This method will close the file associated with the image. See
:ref:`file-handling` for more information.
If the file associated with the image was opened by Pillow, then this
method will close it. The exception to this is if the image has
multiple frames, in which case the file will be left open for seek
operations. See :ref:`file-handling` for more information.
:returns: An image access object.
:rtype: :ref:`PixelAccess` or :py:class:`PIL.PyAccess`