Merge branch 'master' into refs-const

This commit is contained in:
nulano 2020-06-28 10:55:26 +01:00 committed by GitHub
commit 9019af5f32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 318 additions and 299 deletions

View File

@ -249,8 +249,8 @@ class DXT1Decoder(ImageFile.PyDecoder):
def decode(self, buffer): def decode(self, buffer):
try: try:
self.set_as_raw(_dxt1(self.fd, self.state.xsize, self.state.ysize)) self.set_as_raw(_dxt1(self.fd, self.state.xsize, self.state.ysize))
except struct.error: except struct.error as e:
raise OSError("Truncated DDS file") raise OSError("Truncated DDS file") from e
return 0, 0 return 0, 0
@ -260,8 +260,8 @@ class DXT5Decoder(ImageFile.PyDecoder):
def decode(self, buffer): def decode(self, buffer):
try: try:
self.set_as_raw(_dxt5(self.fd, self.state.xsize, self.state.ysize)) self.set_as_raw(_dxt5(self.fd, self.state.xsize, self.state.ysize))
except struct.error: except struct.error as e:
raise OSError("Truncated DDS file") raise OSError("Truncated DDS file") from e
return 0, 0 return 0, 0

View File

@ -8,7 +8,7 @@ Over 30 different file formats can be identified and read by the library.
Write support is less extensive, but most common interchange and presentation Write support is less extensive, but most common interchange and presentation
formats are supported. formats are supported.
The :py:meth:`~PIL.Image.Image.open` function identifies files from their The :py:meth:`~PIL.Image.open` function identifies files from their
contents, not their names, but the :py:meth:`~PIL.Image.Image.save` method contents, not their names, but the :py:meth:`~PIL.Image.Image.save` method
looks at the name to determine which format to use, unless the format is given looks at the name to determine which format to use, unless the format is given
explicitly. explicitly.
@ -25,7 +25,7 @@ Pillow reads and writes Windows and OS/2 BMP files containing ``1``, ``L``, ``P`
or ``RGB`` data. 16-colour images are read as ``P`` images. Run-length encoding or ``RGB`` data. 16-colour images are read as ``P`` images. Run-length encoding
is not supported. is not supported.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**compression** **compression**
@ -74,7 +74,7 @@ are used or GIF89a is already in use.
Note that GIF files are always read as grayscale (``L``) Note that GIF files are always read as grayscale (``L``)
or palette mode (``P``) images. or palette mode (``P``) images.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**background** **background**
@ -203,7 +203,7 @@ ICNS
Pillow reads and (macOS only) writes macOS ``.icns`` files. By default, the Pillow reads and (macOS only) writes macOS ``.icns`` files. By default, the
largest available icon is read, though you can override this by setting the largest available icon is read, though you can override this by setting the
:py:attr:`~PIL.Image.Image.size` property before calling :py:attr:`~PIL.Image.Image.size` property before calling
:py:meth:`~PIL.Image.Image.load`. The :py:meth:`~PIL.Image.Image.open` method :py:meth:`~PIL.Image.Image.load`. The :py:meth:`~PIL.Image.open` method
sets the following :py:attr:`~PIL.Image.Image.info` property: sets the following :py:attr:`~PIL.Image.Image.info` property:
**sizes** **sizes**
@ -257,7 +257,7 @@ Using the :py:meth:`~PIL.Image.Image.draft` method, you can speed things up by
converting ``RGB`` images to ``L``, and resize images to 1/2, 1/4 or 1/8 of converting ``RGB`` images to ``L``, and resize images to 1/2, 1/4 or 1/8 of
their original size while loading them. their original size while loading them.
The :py:meth:`~PIL.Image.Image.open` method may set the following The :py:meth:`~PIL.Image.open` method may set the following
:py:attr:`~PIL.Image.Image.info` properties if available: :py:attr:`~PIL.Image.Image.info` properties if available:
**jfif** **jfif**
@ -697,7 +697,7 @@ Pillow also reads SPIDER stack files containing sequences of SPIDER images. The
:py:meth:`~PIL.Image.Image.seek` and :py:meth:`~PIL.Image.Image.tell` methods are supported, and :py:meth:`~PIL.Image.Image.seek` and :py:meth:`~PIL.Image.Image.tell` methods are supported, and
random access is allowed. random access is allowed.
The :py:meth:`~PIL.Image.Image.open` method sets the following attributes: The :py:meth:`~PIL.Image.open` method sets the following attributes:
**format** **format**
Set to ``SPIDER`` Set to ``SPIDER``
@ -750,7 +750,7 @@ uncompressed files.
support for reading Packbits, LZW and JPEG compressed TIFFs support for reading Packbits, LZW and JPEG compressed TIFFs
without using libtiff. without using libtiff.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**compression** **compression**
@ -1021,7 +1021,7 @@ FLI, FLC
Pillow reads Autodesk FLI and FLC animations. Pillow reads Autodesk FLI and FLC animations.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**duration** **duration**
@ -1054,7 +1054,7 @@ GBR
The GBR decoder reads GIMP brush files, version 1 and 2. The GBR decoder reads GIMP brush files, version 1 and 2.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**comment** **comment**
@ -1069,7 +1069,7 @@ GD
Pillow reads uncompressed GD2 files. Note that you must use Pillow reads uncompressed GD2 files. Note that you must use
:py:func:`PIL.GdImageFile.open` to read such a file. :py:func:`PIL.GdImageFile.open` to read such a file.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**transparency** **transparency**
@ -1185,7 +1185,7 @@ XPM
Pillow reads X pixmap files (mode ``P``) with 256 colors or less. Pillow reads X pixmap files (mode ``P``) with 256 colors or less.
The :py:meth:`~PIL.Image.Image.open` method sets the following The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties: :py:attr:`~PIL.Image.Image.info` properties:
**transparency** **transparency**

View File

@ -76,9 +76,16 @@ Constructing images
.. autofunction:: new .. autofunction:: new
.. autofunction:: fromarray .. autofunction:: fromarray
.. autofunction:: frombytes .. autofunction:: frombytes
.. autofunction:: fromstring
.. autofunction:: frombuffer .. autofunction:: frombuffer
Generating images
^^^^^^^^^^^^^^^^^
.. autofunction:: effect_mandelbrot
.. autofunction:: effect_noise
.. autofunction:: linear_gradient
.. autofunction:: radial_gradient
Registering plugins Registering plugins
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
@ -88,12 +95,14 @@ Registering plugins
ignore them. ignore them.
.. autofunction:: register_open .. autofunction:: register_open
.. autofunction:: register_decoder
.. autofunction:: register_mime .. autofunction:: register_mime
.. autofunction:: register_save .. autofunction:: register_save
.. autofunction:: register_encoder .. autofunction:: register_save_all
.. autofunction:: register_extension .. autofunction:: register_extension
.. autofunction:: register_extensions
.. autofunction:: registered_extensions
.. autofunction:: register_decoder
.. autofunction:: register_encoder
The Image Class The Image Class
--------------- ---------------
@ -140,6 +149,8 @@ This crops the input image with the provided coordinates:
.. automethod:: PIL.Image.Image.draft .. automethod:: PIL.Image.Image.draft
.. automethod:: PIL.Image.Image.effect_spread
.. automethod:: PIL.Image.Image.entropy
.. automethod:: PIL.Image.Image.filter .. automethod:: PIL.Image.Image.filter
This blurs the input image using a filter from the ``ImageFilter`` module: This blurs the input image using a filter from the ``ImageFilter`` module:
@ -176,12 +187,14 @@ This helps to get the bounding box coordinates of the input image:
print(im.getbbox()) print(im.getbbox())
# Returns four coordinates in the format (left, upper, right, lower) # Returns four coordinates in the format (left, upper, right, lower)
.. automethod:: PIL.Image.Image.getchannel
.. automethod:: PIL.Image.Image.getcolors .. automethod:: PIL.Image.Image.getcolors
.. automethod:: PIL.Image.Image.getdata .. automethod:: PIL.Image.Image.getdata
.. automethod:: PIL.Image.Image.getextrema
.. automethod:: PIL.Image.Image.getexif .. automethod:: PIL.Image.Image.getexif
.. automethod:: PIL.Image.Image.getextrema
.. automethod:: PIL.Image.Image.getpalette .. automethod:: PIL.Image.Image.getpalette
.. automethod:: PIL.Image.Image.getpixel .. automethod:: PIL.Image.Image.getpixel
.. automethod:: PIL.Image.Image.getprojection
.. automethod:: PIL.Image.Image.histogram .. automethod:: PIL.Image.Image.histogram
.. automethod:: PIL.Image.Image.offset .. automethod:: PIL.Image.Image.offset
.. automethod:: PIL.Image.Image.paste .. automethod:: PIL.Image.Image.paste
@ -191,6 +204,8 @@ This helps to get the bounding box coordinates of the input image:
.. automethod:: PIL.Image.Image.putpalette .. automethod:: PIL.Image.Image.putpalette
.. automethod:: PIL.Image.Image.putpixel .. automethod:: PIL.Image.Image.putpixel
.. automethod:: PIL.Image.Image.quantize .. automethod:: PIL.Image.Image.quantize
.. automethod:: PIL.Image.Image.reduce
.. automethod:: PIL.Image.Image.remap_palette
.. automethod:: PIL.Image.Image.resize .. automethod:: PIL.Image.Image.resize
This resizes the given image from ``(width, height)`` to ``(width/2, height/2)``: This resizes the given image from ``(width, height)`` to ``(width/2, height/2)``:
@ -205,7 +220,6 @@ This resizes the given image from ``(width, height)`` to ``(width/2, height/2)``
(width, height) = (im.width // 2, im.height // 2) (width, height) = (im.width // 2, im.height // 2)
im_resized = im.resize((width, height)) im_resized = im.resize((width, height))
.. automethod:: PIL.Image.Image.remap_palette
.. automethod:: PIL.Image.Image.rotate .. automethod:: PIL.Image.Image.rotate
This rotates the input image by ``theta`` degrees counter clockwise: This rotates the input image by ``theta`` degrees counter clockwise:
@ -225,7 +239,6 @@ This rotates the input image by ``theta`` degrees counter clockwise:
.. automethod:: PIL.Image.Image.seek .. automethod:: PIL.Image.Image.seek
.. automethod:: PIL.Image.Image.show .. automethod:: PIL.Image.Image.show
.. automethod:: PIL.Image.Image.split .. automethod:: PIL.Image.Image.split
.. automethod:: PIL.Image.Image.getchannel
.. automethod:: PIL.Image.Image.tell .. automethod:: PIL.Image.Image.tell
.. automethod:: PIL.Image.Image.thumbnail .. automethod:: PIL.Image.Image.thumbnail
.. automethod:: PIL.Image.Image.tobitmap .. automethod:: PIL.Image.Image.tobitmap
@ -260,57 +273,51 @@ Attributes
Instances of the :py:class:`Image` class have the following attributes: Instances of the :py:class:`Image` class have the following attributes:
.. py:attribute:: filename .. py:attribute:: Image.filename
:type: str
The filename or path of the source file. Only images created with the The filename or path of the source file. Only images created with the
factory function ``open`` have a filename attribute. If the input is a factory function ``open`` have a filename attribute. If the input is a
file like object, the filename attribute is set to an empty string. file like object, the filename attribute is set to an empty string.
:type: :py:class:`string` .. py:attribute:: Image.format
:type: Optional[str]
.. py:attribute:: format
The file format of the source file. For images created by the library The file format of the source file. For images created by the library
itself (via a factory function, or by running a method on an existing itself (via a factory function, or by running a method on an existing
image), this attribute is set to ``None``. image), this attribute is set to ``None``.
:type: :py:class:`string` or ``None`` .. py:attribute:: Image.mode
:type: str
.. py:attribute:: mode
Image mode. This is a string specifying the pixel format used by the image. Image mode. This is a string specifying the pixel format used by the image.
Typical values are “1”, “L”, “RGB”, or “CMYK.” See Typical values are “1”, “L”, “RGB”, or “CMYK.” See
:ref:`concept-modes` for a full list. :ref:`concept-modes` for a full list.
:type: :py:class:`string` .. py:attribute:: Image.size
:type: tuple[int]
.. py:attribute:: size
Image size, in pixels. The size is given as a 2-tuple (width, height). Image size, in pixels. The size is given as a 2-tuple (width, height).
:type: ``(width, height)`` .. py:attribute:: Image.width
:type: int
.. py:attribute:: width
Image width, in pixels. Image width, in pixels.
:type: :py:class:`int` .. py:attribute:: Image.height
:type: int
.. py:attribute:: height
Image height, in pixels. Image height, in pixels.
:type: :py:class:`int` .. py:attribute:: Image.palette
:type: Optional[PIL.ImagePalette.ImagePalette]
.. py:attribute:: palette
Colour palette table, if any. If mode is "P" or "PA", this should be an Colour palette table, if any. If mode is "P" or "PA", this should be an
instance of the :py:class:`~PIL.ImagePalette.ImagePalette` class. instance of the :py:class:`~PIL.ImagePalette.ImagePalette` class.
Otherwise, it should be set to ``None``. Otherwise, it should be set to ``None``.
:type: :py:class:`~PIL.ImagePalette.ImagePalette` or ``None`` .. py:attribute:: Image.info
:type: dict
.. py:attribute:: info
A dictionary holding data associated with the image. This dictionary is A dictionary holding data associated with the image. This dictionary is
used by file handlers to pass on various non-image information read from used by file handlers to pass on various non-image information read from
@ -323,8 +330,6 @@ Instances of the :py:class:`Image` class have the following attributes:
Unless noted elsewhere, this dictionary does not affect saving files. Unless noted elsewhere, this dictionary does not affect saving files.
:type: :py:class:`dict`
Constants Constants
--------- ---------

View File

@ -8,9 +8,30 @@ The :py:mod:`ImageCms` module provides color profile management
support using the LittleCMS2 color management engine, based on Kevin support using the LittleCMS2 color management engine, based on Kevin
Cazabon's PyCMS library. Cazabon's PyCMS library.
.. automodule:: PIL.ImageCms .. autoclass:: ImageCmsTransform
:members: .. autoexception:: PyCMSError
:noindex:
Functions
---------
.. autofunction:: applyTransform
.. autofunction:: buildProofTransform
.. autofunction:: buildProofTransformFromOpenProfiles
.. autofunction:: buildTransform
.. autofunction:: buildTransformFromOpenProfiles
.. autofunction:: createProfile
.. autofunction:: getDefaultIntent
.. autofunction:: getOpenProfile
.. autofunction:: getProfileCopyright
.. autofunction:: getProfileDescription
.. autofunction:: getProfileInfo
.. autofunction:: getProfileManufacturer
.. autofunction:: getProfileModel
.. autofunction:: getProfileName
.. autofunction:: get_display_profile
.. autofunction:: isIntentSupported
.. autofunction:: profileToProfile
.. autofunction:: versions
CmsProfile CmsProfile
---------- ----------
@ -25,31 +46,30 @@ can be easily displayed in a chromaticity diagram, for example).
.. py:class:: CmsProfile .. py:class:: CmsProfile
.. py:attribute:: creation_date .. py:attribute:: creation_date
:type: Optional[datetime.datetime]
Date and time this profile was first created (see 7.2.1 of ICC.1:2010). Date and time this profile was first created (see 7.2.1 of ICC.1:2010).
:type: :py:class:`datetime.datetime` or ``None``
.. py:attribute:: version .. py:attribute:: version
:type: float
The version number of the ICC standard that this profile follows The version number of the ICC standard that this profile follows
(e.g. ``2.0``). (e.g. ``2.0``).
:type: :py:class:`float`
.. py:attribute:: icc_version .. py:attribute:: icc_version
:type: int
Same as ``version``, but in encoded format (see 7.2.4 of ICC.1:2010). Same as ``version``, but in encoded format (see 7.2.4 of ICC.1:2010).
.. py:attribute:: device_class .. py:attribute:: device_class
:type: str
4-character string identifying the profile class. One of 4-character string identifying the profile class. One of
``scnr``, ``mntr``, ``prtr``, ``link``, ``spac``, ``abst``, ``scnr``, ``mntr``, ``prtr``, ``link``, ``spac``, ``abst``,
``nmcl`` (see 7.2.5 of ICC.1:2010 for details). ``nmcl`` (see 7.2.5 of ICC.1:2010 for details).
:type: :py:class:`string`
.. py:attribute:: xcolor_space .. py:attribute:: xcolor_space
:type: str
4-character string (padded with whitespace) identifying the color 4-character string (padded with whitespace) identifying the color
space, e.g. ``XYZ␣``, ``RGB␣`` or ``CMYK`` (see 7.2.6 of space, e.g. ``XYZ␣``, ``RGB␣`` or ``CMYK`` (see 7.2.6 of
@ -59,9 +79,8 @@ can be easily displayed in a chromaticity diagram, for example).
interpreted (non-padded) variant of this (but can be empty on interpreted (non-padded) variant of this (but can be empty on
unknown input). unknown input).
:type: :py:class:`string`
.. py:attribute:: connection_space .. py:attribute:: connection_space
:type: str
4-character string (padded with whitespace) identifying the color 4-character string (padded with whitespace) identifying the color
space on the B-side of the transform (see 7.2.7 of ICC.1:2010 for space on the B-side of the transform (see 7.2.7 of ICC.1:2010 for
@ -70,42 +89,37 @@ can be easily displayed in a chromaticity diagram, for example).
Note that the deprecated attribute ``pcs`` contains an interpreted Note that the deprecated attribute ``pcs`` contains an interpreted
(non-padded) variant of this (but can be empty on unknown input). (non-padded) variant of this (but can be empty on unknown input).
:type: :py:class:`string`
.. py:attribute:: header_flags .. py:attribute:: header_flags
:type: int
The encoded header flags of the profile (see 7.2.11 of ICC.1:2010 The encoded header flags of the profile (see 7.2.11 of ICC.1:2010
for details). for details).
:type: :py:class:`int`
.. py:attribute:: header_manufacturer .. py:attribute:: header_manufacturer
:type: str
4-character string (padded with whitespace) identifying the device 4-character string (padded with whitespace) identifying the device
manufacturer, which shall match the signature contained in the manufacturer, which shall match the signature contained in the
appropriate section of the ICC signature registry found at appropriate section of the ICC signature registry found at
www.color.org (see 7.2.12 of ICC.1:2010). www.color.org (see 7.2.12 of ICC.1:2010).
:type: :py:class:`string`
.. py:attribute:: header_model .. py:attribute:: header_model
:type: str
4-character string (padded with whitespace) identifying the device 4-character string (padded with whitespace) identifying the device
model, which shall match the signature contained in the model, which shall match the signature contained in the
appropriate section of the ICC signature registry found at appropriate section of the ICC signature registry found at
www.color.org (see 7.2.13 of ICC.1:2010). www.color.org (see 7.2.13 of ICC.1:2010).
:type: :py:class:`string`
.. py:attribute:: attributes .. py:attribute:: attributes
:type: int
Flags used to identify attributes unique to the particular device Flags used to identify attributes unique to the particular device
setup for which the profile is applicable (see 7.2.14 of setup for which the profile is applicable (see 7.2.14 of
ICC.1:2010 for details). ICC.1:2010 for details).
:type: :py:class:`int`
.. py:attribute:: rendering_intent .. py:attribute:: rendering_intent
:type: int
The rendering intent to use when combining this profile with The rendering intent to use when combining this profile with
another profile (usually overridden at run-time, but provided here another profile (usually overridden at run-time, but provided here
@ -114,84 +128,82 @@ can be easily displayed in a chromaticity diagram, for example).
One of ``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC``, ``ImageCms.INTENT_PERCEPTUAL``, One of ``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC``, ``ImageCms.INTENT_PERCEPTUAL``,
``ImageCms.INTENT_RELATIVE_COLORIMETRIC`` and ``ImageCms.INTENT_SATURATION``. ``ImageCms.INTENT_RELATIVE_COLORIMETRIC`` and ``ImageCms.INTENT_SATURATION``.
:type: :py:class:`int`
.. py:attribute:: profile_id .. py:attribute:: profile_id
:type: bytes
A sequence of 16 bytes identifying the profile (via a specially A sequence of 16 bytes identifying the profile (via a specially
constructed MD5 sum), or 16 binary zeroes if the profile ID has constructed MD5 sum), or 16 binary zeroes if the profile ID has
not been calculated (see 7.2.18 of ICC.1:2010). not been calculated (see 7.2.18 of ICC.1:2010).
:type: :py:class:`bytes`
.. py:attribute:: copyright .. py:attribute:: copyright
:type: Optional[str]
The text copyright information for the profile (see 9.2.21 of ICC.1:2010). The text copyright information for the profile (see 9.2.21 of ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: manufacturer .. py:attribute:: manufacturer
:type: Optional[str]
The (English) display string for the device manufacturer (see The (English) display string for the device manufacturer (see
9.2.22 of ICC.1:2010). 9.2.22 of ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: model .. py:attribute:: model
:type: Optional[str]
The (English) display string for the device model of the device The (English) display string for the device model of the device
for which this profile is created (see 9.2.23 of ICC.1:2010). for which this profile is created (see 9.2.23 of ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: profile_description .. py:attribute:: profile_description
:type: Optional[str]
The (English) display string for the profile description (see The (English) display string for the profile description (see
9.2.41 of ICC.1:2010). 9.2.41 of ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: target .. py:attribute:: target
:type: Optional[str]
The name of the registered characterization data set, or the The name of the registered characterization data set, or the
measurement data for a characterization target (see 9.2.14 of measurement data for a characterization target (see 9.2.14 of
ICC.1:2010). ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: red_colorant .. py:attribute:: red_colorant
:type: Optional[tuple[tuple[float]]]
The first column in the matrix used in matrix/TRC transforms (see 9.2.44 of ICC.1:2010). The first column in the matrix used in matrix/TRC transforms (see 9.2.44 of ICC.1:2010).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: green_colorant .. py:attribute:: green_colorant
:type: Optional[tuple[tuple[float]]]
The second column in the matrix used in matrix/TRC transforms (see 9.2.30 of ICC.1:2010). The second column in the matrix used in matrix/TRC transforms (see 9.2.30 of ICC.1:2010).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: blue_colorant .. py:attribute:: blue_colorant
:type: Optional[tuple[tuple[float]]]
The third column in the matrix used in matrix/TRC transforms (see 9.2.4 of ICC.1:2010). The third column in the matrix used in matrix/TRC transforms (see 9.2.4 of ICC.1:2010).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: luminance .. py:attribute:: luminance
:type: Optional[tuple[tuple[float]]]
The absolute luminance of emissive devices in candelas per square The absolute luminance of emissive devices in candelas per square
metre as described by the Y channel (see 9.2.32 of ICC.1:2010). metre as described by the Y channel (see 9.2.32 of ICC.1:2010).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: chromaticity .. py:attribute:: chromaticity
:type: Optional[tuple[tuple[float]]]
The data of the phosphor/colorant chromaticity set used (red, The data of the phosphor/colorant chromaticity set used (red,
green and blue channels, see 9.2.16 of ICC.1:2010). green and blue channels, see 9.2.16 of ICC.1:2010).
:type: ``((x, y, Y), (x, y, Y), (x, y, Y))`` or ``None`` The value is in the format ``((x, y, Y), (x, y, Y), (x, y, Y))``, if available.
.. py:attribute:: chromatic_adaption .. py:attribute:: chromatic_adaption
:type: tuple[tuple[float]]
The chromatic adaption matrix converts a color measured using the The chromatic adaption matrix converts a color measured using the
actual illumination conditions and relative to the actual adopted actual illumination conditions and relative to the actual adopted
@ -199,58 +211,52 @@ can be easily displayed in a chromaticity diagram, for example).
complete adaptation from the actual adopted white chromaticity to complete adaptation from the actual adopted white chromaticity to
the PCS adopted white chromaticity (see 9.2.15 of ICC.1:2010). the PCS adopted white chromaticity (see 9.2.15 of ICC.1:2010).
Two matrices are returned, one in (X, Y, Z) space and one in (x, y, Y) space. Two 3-tuples of floats are returned in a 2-tuple,
one in (X, Y, Z) space and one in (x, y, Y) space.
:type: 2-tuple of 3-tuple, the first with (X, Y, Z) and the second with (x, y, Y) values
.. py:attribute:: colorant_table .. py:attribute:: colorant_table
:type: list[str]
This tag identifies the colorants used in the profile by a unique This tag identifies the colorants used in the profile by a unique
name and set of PCSXYZ or PCSLAB values (see 9.2.19 of name and set of PCSXYZ or PCSLAB values (see 9.2.19 of
ICC.1:2010). ICC.1:2010).
:type: list of strings
.. py:attribute:: colorant_table_out .. py:attribute:: colorant_table_out
:type: list[str]
This tag identifies the colorants used in the profile by a unique This tag identifies the colorants used in the profile by a unique
name and set of PCSLAB values (for DeviceLink profiles only, see name and set of PCSLAB values (for DeviceLink profiles only, see
9.2.19 of ICC.1:2010). 9.2.19 of ICC.1:2010).
:type: list of strings
.. py:attribute:: colorimetric_intent .. py:attribute:: colorimetric_intent
:type: Optional[str]
4-character string (padded with whitespace) identifying the image 4-character string (padded with whitespace) identifying the image
state of PCS colorimetry produced using the colorimetric intent state of PCS colorimetry produced using the colorimetric intent
transforms (see 9.2.20 of ICC.1:2010 for details). transforms (see 9.2.20 of ICC.1:2010 for details).
:type: :py:class:`string` or ``None``
.. py:attribute:: perceptual_rendering_intent_gamut .. py:attribute:: perceptual_rendering_intent_gamut
:type: Optional[str]
4-character string (padded with whitespace) identifying the (one) 4-character string (padded with whitespace) identifying the (one)
standard reference medium gamut (see 9.2.37 of ICC.1:2010 for standard reference medium gamut (see 9.2.37 of ICC.1:2010 for
details). details).
:type: :py:class:`string` or ``None``
.. py:attribute:: saturation_rendering_intent_gamut .. py:attribute:: saturation_rendering_intent_gamut
:type: Optional[str]
4-character string (padded with whitespace) identifying the (one) 4-character string (padded with whitespace) identifying the (one)
standard reference medium gamut (see 9.2.37 of ICC.1:2010 for standard reference medium gamut (see 9.2.37 of ICC.1:2010 for
details). details).
:type: :py:class:`string` or ``None``
.. py:attribute:: technology .. py:attribute:: technology
:type: Optional[str]
4-character string (padded with whitespace) identifying the device 4-character string (padded with whitespace) identifying the device
technology (see 9.2.47 of ICC.1:2010 for details). technology (see 9.2.47 of ICC.1:2010 for details).
:type: :py:class:`string` or ``None``
.. py:attribute:: media_black_point .. py:attribute:: media_black_point
:type: Optional[tuple[tuple[float]]]
This tag specifies the media black point and is used for This tag specifies the media black point and is used for
generating absolute colorimetry. generating absolute colorimetry.
@ -258,57 +264,57 @@ can be easily displayed in a chromaticity diagram, for example).
This tag was available in ICC 3.2, but it is removed from This tag was available in ICC 3.2, but it is removed from
version 4. version 4.
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: media_white_point_temperature .. py:attribute:: media_white_point_temperature
:type: Optional[float]
Calculates the white point temperature (see the LCMS documentation Calculates the white point temperature (see the LCMS documentation
for more information). for more information).
:type: :py:class:`float` or ``None``
.. py:attribute:: viewing_condition .. py:attribute:: viewing_condition
:type: Optional[str]
The (English) display string for the viewing conditions (see The (English) display string for the viewing conditions (see
9.2.48 of ICC.1:2010). 9.2.48 of ICC.1:2010).
:type: :py:class:`unicode` or ``None``
.. py:attribute:: screening_description .. py:attribute:: screening_description
:type: Optional[str]
The (English) display string for the screening conditions. The (English) display string for the screening conditions.
This tag was available in ICC 3.2, but it is removed from This tag was available in ICC 3.2, but it is removed from
version 4. version 4.
:type: :py:class:`unicode` or ``None``
.. py:attribute:: red_primary .. py:attribute:: red_primary
:type: Optional[tuple[tuple[float]]]
The XYZ-transformed of the RGB primary color red (1, 0, 0). The XYZ-transformed of the RGB primary color red (1, 0, 0).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: green_primary .. py:attribute:: green_primary
:type: Optional[tuple[tuple[float]]]
The XYZ-transformed of the RGB primary color green (0, 1, 0). The XYZ-transformed of the RGB primary color green (0, 1, 0).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: blue_primary .. py:attribute:: blue_primary
:type: Optional[tuple[tuple[float]]]
The XYZ-transformed of the RGB primary color blue (0, 0, 1). The XYZ-transformed of the RGB primary color blue (0, 0, 1).
:type: ``((X, Y, Z), (x, y, Y))`` or ``None`` The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.
.. py:attribute:: is_matrix_shaper .. py:attribute:: is_matrix_shaper
:type: bool
True if this profile is implemented as a matrix shaper (see True if this profile is implemented as a matrix shaper (see
documentation on LCMS). documentation on LCMS).
:type: :py:class:`bool`
.. py:attribute:: clut .. py:attribute:: clut
:type: dict[tuple[bool]]
Returns a dictionary of all supported intents and directions for Returns a dictionary of all supported intents and directions for
the CLUT model. the CLUT model.
@ -326,9 +332,8 @@ can be easily displayed in a chromaticity diagram, for example).
The elements of the tuple are booleans. If the value is ``True``, The elements of the tuple are booleans. If the value is ``True``,
that intent is supported for that direction. that intent is supported for that direction.
:type: :py:class:`dict` of boolean 3-tuples
.. py:attribute:: intent_supported .. py:attribute:: intent_supported
:type: dict[tuple[bool]]
Returns a dictionary of all supported intents and directions. Returns a dictionary of all supported intents and directions.
@ -345,53 +350,46 @@ can be easily displayed in a chromaticity diagram, for example).
The elements of the tuple are booleans. If the value is ``True``, The elements of the tuple are booleans. If the value is ``True``,
that intent is supported for that direction. that intent is supported for that direction.
:type: :py:class:`dict` of boolean 3-tuples
.. py:attribute:: color_space .. py:attribute:: color_space
:type: str
Deprecated but retained for backwards compatibility. Deprecated but retained for backwards compatibility.
Interpreted value of :py:attr:`.xcolor_space`. May be the Interpreted value of :py:attr:`.xcolor_space`. May be the
empty string if value could not be decoded. empty string if value could not be decoded.
:type: :py:class:`string`
.. py:attribute:: pcs .. py:attribute:: pcs
:type: str
Deprecated but retained for backwards compatibility. Deprecated but retained for backwards compatibility.
Interpreted value of :py:attr:`.connection_space`. May be Interpreted value of :py:attr:`.connection_space`. May be
the empty string if value could not be decoded. the empty string if value could not be decoded.
:type: :py:class:`string`
.. py:attribute:: product_model .. py:attribute:: product_model
:type: str
Deprecated but retained for backwards compatibility. Deprecated but retained for backwards compatibility.
ASCII-encoded value of :py:attr:`.model`. ASCII-encoded value of :py:attr:`.model`.
:type: :py:class:`string`
.. py:attribute:: product_manufacturer .. py:attribute:: product_manufacturer
:type: str
Deprecated but retained for backwards compatibility. Deprecated but retained for backwards compatibility.
ASCII-encoded value of :py:attr:`.manufacturer`. ASCII-encoded value of :py:attr:`.manufacturer`.
:type: :py:class:`string`
.. py:attribute:: product_copyright .. py:attribute:: product_copyright
:type: str
Deprecated but retained for backwards compatibility. Deprecated but retained for backwards compatibility.
ASCII-encoded value of :py:attr:`.copyright`. ASCII-encoded value of :py:attr:`.copyright`.
:type: :py:class:`string`
.. py:attribute:: product_description .. py:attribute:: product_description
:type: str
Deprecated but retained for backwards compatibility. Deprecated but retained for backwards compatibility.
ASCII-encoded value of :py:attr:`.profile_description`. ASCII-encoded value of :py:attr:`.profile_description`.
:type: :py:class:`string`
.. py:attribute:: product_desc .. py:attribute:: product_desc
:type: str
Deprecated but retained for backwards compatibility. Deprecated but retained for backwards compatibility.
ASCII-encoded value of :py:attr:`.profile_description`. ASCII-encoded value of :py:attr:`.profile_description`.
@ -401,8 +399,6 @@ can be easily displayed in a chromaticity diagram, for example).
depending on the value of the description, copyright, depending on the value of the description, copyright,
manufacturer and model fields). manufacturer and model fields).
:type: :py:class:`string`
There is one function defined on the class: There is one function defined on the class:
.. py:method:: is_intent_supported(intent, direction) .. py:method:: is_intent_supported(intent, direction)

View File

@ -34,14 +34,21 @@ Example: Parse an image
im.save("copy.jpg") im.save("copy.jpg")
:py:class:`~PIL.ImageFile.Parser` Classes
--------------------------------- -------
.. autoclass:: PIL.ImageFile.Parser() .. autoclass:: PIL.ImageFile.Parser()
:members: :members:
:py:class:`~PIL.ImageFile.PyDecoder`
------------------------------------
.. autoclass:: PIL.ImageFile.PyDecoder() .. autoclass:: PIL.ImageFile.PyDecoder()
:members: :members:
.. autoclass:: PIL.ImageFile.ImageFile()
:member-order: bysource
:members:
:undoc-members:
:show-inheritance:
.. autoclass:: PIL.ImageFile.StubImageFile()
:members:
:show-inheritance:

View File

@ -98,20 +98,24 @@ These functions are applied to each individual pixel.
.. py:currentmodule:: None .. py:currentmodule:: None
.. py:function:: abs(image) .. py:function:: abs(image)
:noindex:
Absolute value. Absolute value.
.. py:function:: convert(image, mode) .. py:function:: convert(image, mode)
:noindex:
Convert image to the given mode. The mode must be given as a string Convert image to the given mode. The mode must be given as a string
constant. constant.
.. py:function:: float(image) .. py:function:: float(image)
:noindex:
Convert image to 32-bit floating point. This is equivalent to Convert image to 32-bit floating point. This is equivalent to
convert(image, “F”). convert(image, “F”).
.. py:function:: int(image) .. py:function:: int(image)
:noindex:
Convert image to 32-bit integer. This is equivalent to convert(image, “I”). Convert image to 32-bit integer. This is equivalent to convert(image, “I”).
@ -119,9 +123,11 @@ These functions are applied to each individual pixel.
integers if necessary to get a correct result. integers if necessary to get a correct result.
.. py:function:: max(image1, image2) .. py:function:: max(image1, image2)
:noindex:
Maximum value. Maximum value.
.. py:function:: min(image1, image2) .. py:function:: min(image1, image2)
:noindex:
Minimum value. Minimum value.

View File

@ -282,8 +282,8 @@ class _BLPBaseDecoder(ImageFile.PyDecoder):
self.magic = self.fd.read(4) self.magic = self.fd.read(4)
self._read_blp_header() self._read_blp_header()
self._load() self._load()
except struct.error: except struct.error as e:
raise OSError("Truncated Blp file") raise OSError("Truncated Blp file") from e
return 0, 0 return 0, 0
def _read_palette(self): def _read_palette(self):

View File

@ -304,8 +304,8 @@ def _dib_save(im, fp, filename):
def _save(im, fp, filename, bitmap_header=True): def _save(im, fp, filename, bitmap_header=True):
try: try:
rawmode, bits, colors = SAVE[im.mode] rawmode, bits, colors = SAVE[im.mode]
except KeyError: except KeyError as e:
raise OSError("cannot write mode %s as BMP" % im.mode) raise OSError("cannot write mode %s as BMP" % im.mode) from e
info = im.encoderinfo info = im.encoderinfo

View File

@ -231,8 +231,8 @@ class EpsImageFile(ImageFile.ImageFile):
try: try:
m = split.match(s) m = split.match(s)
except re.error: except re.error as e:
raise SyntaxError("not an EPS file") raise SyntaxError("not an EPS file") from e
if m: if m:
k, v = m.group(1, 2) k, v = m.group(1, 2)

View File

@ -59,8 +59,8 @@ class FpxImageFile(ImageFile.ImageFile):
try: try:
self.ole = olefile.OleFileIO(self.fp) self.ole = olefile.OleFileIO(self.fp)
except OSError: except OSError as e:
raise SyntaxError("not an FPX file; invalid OLE file") raise SyntaxError("not an FPX file; invalid OLE file") from e
if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B": if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B":
raise SyntaxError("not an FPX file; bad root CLSID") raise SyntaxError("not an FPX file; bad root CLSID")

View File

@ -85,5 +85,5 @@ def open(fp, mode="r"):
try: try:
return GdImageFile(fp) return GdImageFile(fp)
except SyntaxError: except SyntaxError as e:
raise UnidentifiedImageError("cannot identify this image file") raise UnidentifiedImageError("cannot identify this image file") from e

View File

@ -130,9 +130,9 @@ class GifImageFile(ImageFile.ImageFile):
for f in range(self.__frame + 1, frame + 1): for f in range(self.__frame + 1, frame + 1):
try: try:
self._seek(f) self._seek(f)
except EOFError: except EOFError as e:
self.seek(last_frame) self.seek(last_frame)
raise EOFError("no more images in GIF file") raise EOFError("no more images in GIF file") from e
def _seek(self, frame): def _seek(self, frame):

View File

@ -163,8 +163,8 @@ class ImImageFile(ImageFile.ImageFile):
try: try:
m = split.match(s) m = split.match(s)
except re.error: except re.error as e:
raise SyntaxError("not an IM file") raise SyntaxError("not an IM file") from e
if m: if m:
@ -341,8 +341,8 @@ def _save(im, fp, filename):
try: try:
image_type, rawmode = SAVE[im.mode] image_type, rawmode = SAVE[im.mode]
except KeyError: except KeyError as e:
raise ValueError("Cannot save %s images as IM" % im.mode) raise ValueError("Cannot save %s images as IM" % im.mode) from e
frames = im.encoderinfo.get("frames", 1) frames = im.encoderinfo.get("frames", 1)

View File

@ -434,8 +434,8 @@ def _getdecoder(mode, decoder_name, args, extra=()):
try: try:
# get decoder # get decoder
decoder = getattr(core, decoder_name + "_decoder") decoder = getattr(core, decoder_name + "_decoder")
except AttributeError: except AttributeError as e:
raise OSError("decoder %s not available" % decoder_name) raise OSError("decoder %s not available" % decoder_name) from e
return decoder(mode, *args + extra) return decoder(mode, *args + extra)
@ -457,8 +457,8 @@ def _getencoder(mode, encoder_name, args, extra=()):
try: try:
# get encoder # get encoder
encoder = getattr(core, encoder_name + "_encoder") encoder = getattr(core, encoder_name + "_encoder")
except AttributeError: except AttributeError as e:
raise OSError("encoder %s not available" % encoder_name) raise OSError("encoder %s not available" % encoder_name) from e
return encoder(mode, *args + extra) return encoder(mode, *args + extra)
@ -971,10 +971,10 @@ class Image:
if isinstance(t, tuple): if isinstance(t, tuple):
try: try:
t = trns_im.palette.getcolor(t) t = trns_im.palette.getcolor(t)
except Exception: except Exception as e:
raise ValueError( raise ValueError(
"Couldn't allocate a palette color for transparency" "Couldn't allocate a palette color for transparency"
) ) from e
trns_im.putpixel((0, 0), t) trns_im.putpixel((0, 0), t)
if mode in ("L", "RGB"): if mode in ("L", "RGB"):
@ -1027,8 +1027,8 @@ class Image:
# normalize source image and try again # normalize source image and try again
im = self.im.convert(getmodebase(self.mode)) im = self.im.convert(getmodebase(self.mode))
im = im.convert(mode, dither) im = im.convert(mode, dither)
except KeyError: except KeyError as e:
raise ValueError("illegal conversion") raise ValueError("illegal conversion") from e
new_im = self._new(im) new_im = self._new(im)
if delete_trns: if delete_trns:
@ -1625,16 +1625,16 @@ class Image:
mode = getmodebase(self.mode) + "A" mode = getmodebase(self.mode) + "A"
try: try:
self.im.setmode(mode) self.im.setmode(mode)
except (AttributeError, ValueError): except (AttributeError, ValueError) as e:
# do things the hard way # do things the hard way
im = self.im.convert(mode) im = self.im.convert(mode)
if im.mode not in ("LA", "PA", "RGBA"): if im.mode not in ("LA", "PA", "RGBA"):
raise ValueError # sanity check raise ValueError from e # sanity check
self.im = im self.im = im
self.pyaccess = None self.pyaccess = None
self.mode = self.im.mode self.mode = self.im.mode
except (KeyError, ValueError): except (KeyError, ValueError) as e:
raise ValueError("illegal image mode") raise ValueError("illegal image mode") from e
if self.mode in ("LA", "PA"): if self.mode in ("LA", "PA"):
band = 1 band = 1
@ -2136,8 +2136,8 @@ class Image:
init() init()
try: try:
format = EXTENSION[ext] format = EXTENSION[ext]
except KeyError: except KeyError as e:
raise ValueError("unknown file extension: {}".format(ext)) raise ValueError("unknown file extension: {}".format(ext)) from e
if format.upper() not in SAVE: if format.upper() not in SAVE:
init() init()
@ -2245,8 +2245,8 @@ class Image:
if isinstance(channel, str): if isinstance(channel, str):
try: try:
channel = self.getbands().index(channel) channel = self.getbands().index(channel)
except ValueError: except ValueError as e:
raise ValueError('The image has no channel "{}"'.format(channel)) raise ValueError('The image has no channel "{}"'.format(channel)) from e
return self._new(self.im.getband(channel)) return self._new(self.im.getband(channel))
@ -2743,12 +2743,12 @@ def fromarray(obj, mode=None):
if mode is None: if mode is None:
try: try:
typekey = (1, 1) + shape[2:], arr["typestr"] typekey = (1, 1) + shape[2:], arr["typestr"]
except KeyError: except KeyError as e:
raise TypeError("Cannot handle this data type") raise TypeError("Cannot handle this data type") from e
try: try:
mode, rawmode = _fromarray_typemap[typekey] mode, rawmode = _fromarray_typemap[typekey]
except KeyError: except KeyError as e:
raise TypeError("Cannot handle this data type: %s, %s" % typekey) raise TypeError("Cannot handle this data type: %s, %s" % typekey) from e
else: else:
rawmode = mode rawmode = mode
if mode in ["1", "L", "I", "P", "F"]: if mode in ["1", "L", "I", "P", "F"]:

View File

@ -295,11 +295,12 @@ def profileToProfile(
``inputProfile`` to ``outputProfile``. ``inputProfile`` to ``outputProfile``.
If the input or output profiles specified are not valid filenames, a If the input or output profiles specified are not valid filenames, a
``PyCMSError`` will be raised. If ``inPlace`` is ``True`` and :exc:`PyCMSError` will be raised. If ``inPlace`` is ``True`` and
``outputMode != im.mode``, a ``PyCMSError`` will be raised. If an error ``outputMode != im.mode``, a :exc:`PyCMSError` will be raised.
occurs during application of the profiles, a ``PyCMSError`` will be raised. If an error occurs during application of the profiles,
a :exc:`PyCMSError` will be raised.
If ``outputMode`` is not a mode supported by the ``outputProfile`` (or by pyCMS), If ``outputMode`` is not a mode supported by the ``outputProfile`` (or by pyCMS),
a ``PyCMSError`` will be raised. a :exc:`PyCMSError` will be raised.
This function applies an ICC transformation to im from ``inputProfile``'s This function applies an ICC transformation to im from ``inputProfile``'s
color space to ``outputProfile``'s color space using the specified rendering color space to ``outputProfile``'s color space using the specified rendering
@ -369,7 +370,7 @@ def profileToProfile(
else: else:
imOut = transform.apply(im) imOut = transform.apply(im)
except (OSError, TypeError, ValueError) as v: except (OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
return imOut return imOut
@ -381,8 +382,8 @@ def getOpenProfile(profileFilename):
The PyCMSProfile object can be passed back into pyCMS for use in creating The PyCMSProfile object can be passed back into pyCMS for use in creating
transforms and such (as in ImageCms.buildTransformFromOpenProfiles()). transforms and such (as in ImageCms.buildTransformFromOpenProfiles()).
If ``profileFilename`` is not a valid filename for an ICC profile, a ``PyCMSError`` If ``profileFilename`` is not a valid filename for an ICC profile,
will be raised. a :exc:`PyCMSError` will be raised.
:param profileFilename: String, as a valid filename path to the ICC profile :param profileFilename: String, as a valid filename path to the ICC profile
you wish to open, or a file-like object. you wish to open, or a file-like object.
@ -393,7 +394,7 @@ def getOpenProfile(profileFilename):
try: try:
return ImageCmsProfile(profileFilename) return ImageCmsProfile(profileFilename)
except (OSError, TypeError, ValueError) as v: except (OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def buildTransform( def buildTransform(
@ -410,11 +411,11 @@ def buildTransform(
image. image.
If the input or output profiles specified are not valid filenames, a If the input or output profiles specified are not valid filenames, a
``PyCMSError`` will be raised. If an error occurs during creation of the :exc:`PyCMSError` will be raised. If an error occurs during creation
transform, a ``PyCMSError`` will be raised. of the transform, a :exc:`PyCMSError` will be raised.
If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile`` If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile``
(or by pyCMS), a ``PyCMSError`` will be raised. (or by pyCMS), a :exc:`PyCMSError` will be raised.
This function builds and returns an ICC transform from the ``inputProfile`` This function builds and returns an ICC transform from the ``inputProfile``
to the ``outputProfile`` using the ``renderingIntent`` to determine what to do to the ``outputProfile`` using the ``renderingIntent`` to determine what to do
@ -474,7 +475,7 @@ def buildTransform(
inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags
) )
except (OSError, TypeError, ValueError) as v: except (OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def buildProofTransform( def buildProofTransform(
@ -493,13 +494,13 @@ def buildProofTransform(
obtained on the ``proofProfile`` device. obtained on the ``proofProfile`` device.
If the input, output, or proof profiles specified are not valid If the input, output, or proof profiles specified are not valid
filenames, a ``PyCMSError`` will be raised. filenames, a :exc:`PyCMSError` will be raised.
If an error occurs during creation of the transform, a ``PyCMSError`` If an error occurs during creation of the transform,
will be raised. a :exc:`PyCMSError` will be raised.
If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile`` If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile``
(or by pyCMS), a ``PyCMSError`` will be raised. (or by pyCMS), a :exc:`PyCMSError` will be raised.
This function builds and returns an ICC transform from the ``inputProfile`` This function builds and returns an ICC transform from the ``inputProfile``
to the ``outputProfile``, but tries to simulate the result that would be to the ``outputProfile``, but tries to simulate the result that would be
@ -585,7 +586,7 @@ def buildProofTransform(
flags, flags,
) )
except (OSError, TypeError, ValueError) as v: except (OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
buildTransformFromOpenProfiles = buildTransform buildTransformFromOpenProfiles = buildTransform
@ -596,17 +597,17 @@ def applyTransform(im, transform, inPlace=False):
""" """
(pyCMS) Applies a transform to a given image. (pyCMS) Applies a transform to a given image.
If ``im.mode != transform.inMode``, a ``PyCMSError`` is raised. If ``im.mode != transform.inMode``, a :exc:`PyCMSError` is raised.
If ``inPlace`` is ``True`` and ``transform.inMode != transform.outMode``, a If ``inPlace`` is ``True`` and ``transform.inMode != transform.outMode``, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If ``im.mode``, ``transform.inMode`` or ``transform.outMode`` is not If ``im.mode``, ``transform.inMode`` or ``transform.outMode`` is not
supported by pyCMSdll or the profiles you used for the transform, a supported by pyCMSdll or the profiles you used for the transform, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while the transform is being applied, a ``PyCMSError`` If an error occurs while the transform is being applied,
is raised. a :exc:`PyCMSError` is raised.
This function applies a pre-calculated transform (from This function applies a pre-calculated transform (from
ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles()) ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles())
@ -640,7 +641,7 @@ def applyTransform(im, transform, inPlace=False):
else: else:
imOut = transform.apply(im) imOut = transform.apply(im)
except (TypeError, ValueError) as v: except (TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
return imOut return imOut
@ -649,12 +650,14 @@ def createProfile(colorSpace, colorTemp=-1):
""" """
(pyCMS) Creates a profile. (pyCMS) Creates a profile.
If colorSpace not in ``["LAB", "XYZ", "sRGB"]``, a ``PyCMSError`` is raised. If colorSpace not in ``["LAB", "XYZ", "sRGB"]``,
a :exc:`PyCMSError` is raised.
If using LAB and ``colorTemp`` is not a positive integer, a ``PyCMSError`` is If using LAB and ``colorTemp`` is not a positive integer,
raised. a :exc:`PyCMSError` is raised.
If an error occurs while creating the profile, a ``PyCMSError`` is raised. If an error occurs while creating the profile,
a :exc:`PyCMSError` is raised.
Use this function to create common profiles on-the-fly instead of Use this function to create common profiles on-the-fly instead of
having to supply a profile on disk and knowing the path to it. It having to supply a profile on disk and knowing the path to it. It
@ -682,15 +685,15 @@ def createProfile(colorSpace, colorTemp=-1):
if colorSpace == "LAB": if colorSpace == "LAB":
try: try:
colorTemp = float(colorTemp) colorTemp = float(colorTemp)
except (TypeError, ValueError): except (TypeError, ValueError) as e:
raise PyCMSError( raise PyCMSError(
'Color temperature must be numeric, "%s" not valid' % colorTemp 'Color temperature must be numeric, "%s" not valid' % colorTemp
) ) from e
try: try:
return core.createProfile(colorSpace, colorTemp) return core.createProfile(colorSpace, colorTemp)
except (TypeError, ValueError) as v: except (TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileName(profile): def getProfileName(profile):
@ -699,8 +702,8 @@ def getProfileName(profile):
(pyCMS) Gets the internal product name for the given profile. (pyCMS) Gets the internal product name for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, If ``profile`` isn't a valid CmsProfile object or filename to a profile,
a ``PyCMSError`` is raised If an error occurs while trying to obtain the a :exc:`PyCMSError` is raised If an error occurs while trying
name tag, a ``PyCMSError`` is raised. to obtain the name tag, a :exc:`PyCMSError` is raised.
Use this function to obtain the INTERNAL name of the profile (stored Use this function to obtain the INTERNAL name of the profile (stored
in an ICC tag in the profile itself), usually the one used when the in an ICC tag in the profile itself), usually the one used when the
@ -732,7 +735,7 @@ def getProfileName(profile):
return "{} - {}\n".format(model, manufacturer) return "{} - {}\n".format(model, manufacturer)
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileInfo(profile): def getProfileInfo(profile):
@ -740,10 +743,10 @@ def getProfileInfo(profile):
(pyCMS) Gets the internal product information for the given profile. (pyCMS) Gets the internal product information for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, If ``profile`` isn't a valid CmsProfile object or filename to a profile,
a ``PyCMSError`` is raised. a :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the info tag, a ``PyCMSError`` If an error occurs while trying to obtain the info tag,
is raised. a :exc:`PyCMSError` is raised.
Use this function to obtain the information stored in the profile's Use this function to obtain the information stored in the profile's
info tag. This often contains details about the profile, and how it info tag. This often contains details about the profile, and how it
@ -772,7 +775,7 @@ def getProfileInfo(profile):
return "\r\n\r\n".join(arr) + "\r\n\r\n" return "\r\n\r\n".join(arr) + "\r\n\r\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileCopyright(profile): def getProfileCopyright(profile):
@ -780,10 +783,10 @@ def getProfileCopyright(profile):
(pyCMS) Gets the copyright for the given profile. (pyCMS) Gets the copyright for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, a If ``profile`` isn't a valid CmsProfile object or filename to a profile, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the copyright tag, a ``PyCMSError`` If an error occurs while trying to obtain the copyright tag,
is raised. a :exc:`PyCMSError` is raised.
Use this function to obtain the information stored in the profile's Use this function to obtain the information stored in the profile's
copyright tag. copyright tag.
@ -800,7 +803,7 @@ def getProfileCopyright(profile):
profile = ImageCmsProfile(profile) profile = ImageCmsProfile(profile)
return (profile.profile.copyright or "") + "\n" return (profile.profile.copyright or "") + "\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileManufacturer(profile): def getProfileManufacturer(profile):
@ -808,10 +811,10 @@ def getProfileManufacturer(profile):
(pyCMS) Gets the manufacturer for the given profile. (pyCMS) Gets the manufacturer for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, a If ``profile`` isn't a valid CmsProfile object or filename to a profile, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the manufacturer tag, a If an error occurs while trying to obtain the manufacturer tag, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
Use this function to obtain the information stored in the profile's Use this function to obtain the information stored in the profile's
manufacturer tag. manufacturer tag.
@ -828,7 +831,7 @@ def getProfileManufacturer(profile):
profile = ImageCmsProfile(profile) profile = ImageCmsProfile(profile)
return (profile.profile.manufacturer or "") + "\n" return (profile.profile.manufacturer or "") + "\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileModel(profile): def getProfileModel(profile):
@ -836,10 +839,10 @@ def getProfileModel(profile):
(pyCMS) Gets the model for the given profile. (pyCMS) Gets the model for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, a If ``profile`` isn't a valid CmsProfile object or filename to a profile, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the model tag, a ``PyCMSError`` If an error occurs while trying to obtain the model tag,
is raised. a :exc:`PyCMSError` is raised.
Use this function to obtain the information stored in the profile's Use this function to obtain the information stored in the profile's
model tag. model tag.
@ -857,7 +860,7 @@ def getProfileModel(profile):
profile = ImageCmsProfile(profile) profile = ImageCmsProfile(profile)
return (profile.profile.model or "") + "\n" return (profile.profile.model or "") + "\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getProfileDescription(profile): def getProfileDescription(profile):
@ -865,10 +868,10 @@ def getProfileDescription(profile):
(pyCMS) Gets the description for the given profile. (pyCMS) Gets the description for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, a If ``profile`` isn't a valid CmsProfile object or filename to a profile, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the description tag, a ``PyCMSError`` If an error occurs while trying to obtain the description tag,
is raised. a :exc:`PyCMSError` is raised.
Use this function to obtain the information stored in the profile's Use this function to obtain the information stored in the profile's
description tag. description tag.
@ -886,7 +889,7 @@ def getProfileDescription(profile):
profile = ImageCmsProfile(profile) profile = ImageCmsProfile(profile)
return (profile.profile.profile_description or "") + "\n" return (profile.profile.profile_description or "") + "\n"
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def getDefaultIntent(profile): def getDefaultIntent(profile):
@ -894,10 +897,10 @@ def getDefaultIntent(profile):
(pyCMS) Gets the default intent name for the given profile. (pyCMS) Gets the default intent name for the given profile.
If ``profile`` isn't a valid CmsProfile object or filename to a profile, a If ``profile`` isn't a valid CmsProfile object or filename to a profile, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
If an error occurs while trying to obtain the default intent, a If an error occurs while trying to obtain the default intent, a
``PyCMSError`` is raised. :exc:`PyCMSError` is raised.
Use this function to determine the default (and usually best optimized) Use this function to determine the default (and usually best optimized)
rendering intent for this profile. Most profiles support multiple rendering intent for this profile. Most profiles support multiple
@ -925,7 +928,7 @@ def getDefaultIntent(profile):
profile = ImageCmsProfile(profile) profile = ImageCmsProfile(profile)
return profile.profile.rendering_intent return profile.profile.rendering_intent
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def isIntentSupported(profile, intent, direction): def isIntentSupported(profile, intent, direction):
@ -940,8 +943,8 @@ def isIntentSupported(profile, intent, direction):
be used for others. Some profiles can only be used for certain be used for others. Some profiles can only be used for certain
rendering intents, so it's best to either verify this before trying rendering intents, so it's best to either verify this before trying
to create a transform with them (using this function), or catch the to create a transform with them (using this function), or catch the
potential ``PyCMSError`` that will occur if they don't support the modes potential :exc:`PyCMSError` that will occur if they don't
you select. support the modes you select.
:param profile: EITHER a valid CmsProfile object, OR a string of the :param profile: EITHER a valid CmsProfile object, OR a string of the
filename of an ICC profile. filename of an ICC profile.
@ -976,7 +979,7 @@ def isIntentSupported(profile, intent, direction):
else: else:
return -1 return -1
except (AttributeError, OSError, TypeError, ValueError) as v: except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) raise PyCMSError(v) from v
def versions(): def versions():

View File

@ -106,7 +106,7 @@ class Draw:
def chord(self, xy, start, end, *options): def chord(self, xy, start, end, *options):
""" """
Same as :py:meth:`~PIL.ImageDraw2.ImageDraw.arc`, but connects the end points Same as :py:meth:`~PIL.ImageDraw2.Draw.arc`, but connects the end points
with a straight line. with a straight line.
.. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.chord` .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.chord`

View File

@ -85,7 +85,7 @@ def _tilesort(t):
class ImageFile(Image.Image): class ImageFile(Image.Image):
"Base class for image file format handlers." """Base class for image file format handlers."""
def __init__(self, fp=None, filename=None): def __init__(self, fp=None, filename=None):
super().__init__() super().__init__()
@ -122,7 +122,7 @@ class ImageFile(Image.Image):
EOFError, # got header but not the first frame EOFError, # got header but not the first frame
struct.error, struct.error,
) as v: ) as v:
raise SyntaxError(v) raise SyntaxError(v) from v
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")
@ -241,12 +241,12 @@ class ImageFile(Image.Image):
while True: while True:
try: try:
s = read(self.decodermaxblock) s = read(self.decodermaxblock)
except (IndexError, struct.error): except (IndexError, struct.error) as e:
# truncated png/gif # truncated png/gif
if LOAD_TRUNCATED_IMAGES: if LOAD_TRUNCATED_IMAGES:
break break
else: else:
raise OSError("image file is truncated") raise OSError("image file is truncated") from e
if not s: # truncated jpeg if not s: # truncated jpeg
if LOAD_TRUNCATED_IMAGES: if LOAD_TRUNCATED_IMAGES:
@ -505,7 +505,7 @@ def _save(im, fp, tile, bufsize=0):
try: try:
fh = fp.fileno() fh = fp.fileno()
fp.flush() fp.flush()
except (AttributeError, io.UnsupportedOperation): except (AttributeError, io.UnsupportedOperation) as e:
# compress to Python file-compatible object # compress to Python file-compatible object
for e, b, o, a in tile: for e, b, o, a in tile:
e = Image._getencoder(im.mode, e, a, im.encoderconfig) e = Image._getencoder(im.mode, e, a, im.encoderconfig)
@ -522,7 +522,7 @@ def _save(im, fp, tile, bufsize=0):
if s: if s:
break break
if s < 0: if s < 0:
raise OSError("encoder error %d when writing image file" % s) raise OSError("encoder error %d when writing image file" % s) from e
e.cleanup() e.cleanup()
else: else:
# slight speedup: compress to real file object # slight speedup: compress to real file object

View File

@ -411,10 +411,10 @@ class Color3DLUT(MultibandFilter):
def _check_size(size): def _check_size(size):
try: try:
_, _, _ = size _, _, _ = size
except ValueError: except ValueError as e:
raise ValueError( raise ValueError(
"Size should be either an integer or a tuple of three integers." "Size should be either an integer or a tuple of three integers."
) ) from e
except TypeError: except TypeError:
size = (size, size, size) size = (size, size, size)
size = [int(x) for x in size] size = [int(x) for x in size]

View File

@ -505,8 +505,8 @@ class FreeTypeFont:
""" """
try: try:
names = self.font.getvarnames() names = self.font.getvarnames()
except AttributeError: except AttributeError as e:
raise NotImplementedError("FreeType 2.9.1 or greater is required") raise NotImplementedError("FreeType 2.9.1 or greater is required") from e
return [name.replace(b"\x00", b"") for name in names] return [name.replace(b"\x00", b"") for name in names]
def set_variation_by_name(self, name): def set_variation_by_name(self, name):
@ -535,8 +535,8 @@ class FreeTypeFont:
""" """
try: try:
axes = self.font.getvaraxes() axes = self.font.getvaraxes()
except AttributeError: except AttributeError as e:
raise NotImplementedError("FreeType 2.9.1 or greater is required") raise NotImplementedError("FreeType 2.9.1 or greater is required") from e
for axis in axes: for axis in axes:
axis["name"] = axis["name"].replace(b"\x00", b"") axis["name"] = axis["name"].replace(b"\x00", b"")
return axes return axes
@ -548,8 +548,8 @@ class FreeTypeFont:
""" """
try: try:
self.font.setvaraxes(axes) self.font.setvaraxes(axes)
except AttributeError: except AttributeError as e:
raise NotImplementedError("FreeType 2.9.1 or greater is required") raise NotImplementedError("FreeType 2.9.1 or greater is required") from e
class TransposedFont: class TransposedFont:

View File

@ -57,8 +57,8 @@ class _Operand:
im1.load() im1.load()
try: try:
op = getattr(_imagingmath, op + "_" + im1.mode) op = getattr(_imagingmath, op + "_" + im1.mode)
except AttributeError: except AttributeError as e:
raise TypeError("bad operand type for '%s'" % op) raise TypeError("bad operand type for '%s'" % op) from e
_imagingmath.unop(op, out.im.id, im1.im.id) _imagingmath.unop(op, out.im.id, im1.im.id)
else: else:
# binary operation # binary operation
@ -85,8 +85,8 @@ class _Operand:
im2.load() im2.load()
try: try:
op = getattr(_imagingmath, op + "_" + im1.mode) op = getattr(_imagingmath, op + "_" + im1.mode)
except AttributeError: except AttributeError as e:
raise TypeError("bad operand type for '%s'" % op) raise TypeError("bad operand type for '%s'" % op) from e
_imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id) _imagingmath.binop(op, out.im.id, im1.im.id, im2.im.id)
return _Operand(out) return _Operand(out)

View File

@ -97,13 +97,13 @@ class ImagePalette:
if isinstance(color, tuple): if isinstance(color, tuple):
try: try:
return self.colors[color] return self.colors[color]
except KeyError: except KeyError as e:
# allocate new color slot # allocate new color slot
if isinstance(self.palette, bytes): if isinstance(self.palette, bytes):
self.palette = bytearray(self.palette) self.palette = bytearray(self.palette)
index = len(self.colors) index = len(self.colors)
if index >= 256: if index >= 256:
raise ValueError("cannot allocate more than 256 colors") raise ValueError("cannot allocate more than 256 colors") from e
self.colors[color] = index self.colors[color] = index
self.palette[index] = color[0] self.palette[index] = color[0]
self.palette[index + 256] = color[1] self.palette[index + 256] = color[1]

View File

@ -38,8 +38,8 @@ class Iterator:
try: try:
self.im.seek(ix) self.im.seek(ix)
return self.im return self.im
except EOFError: except EOFError as e:
raise IndexError # end of sequence raise IndexError from e # end of sequence
def __iter__(self): def __iter__(self):
return self return self
@ -49,8 +49,8 @@ class Iterator:
self.im.seek(self.position) self.im.seek(self.position)
self.position += 1 self.position += 1
return self.im return self.im
except EOFError: except EOFError as e:
raise StopIteration raise StopIteration from e
def all_frames(im, func=None): def all_frames(im, func=None):

View File

@ -118,8 +118,8 @@ class IptcImageFile(ImageFile.ImageFile):
# compression # compression
try: try:
compression = COMPRESSION[self.getint((3, 120))] compression = COMPRESSION[self.getint((3, 120))]
except KeyError: except KeyError as e:
raise OSError("Unknown IPTC image compression") raise OSError("Unknown IPTC image compression") from e
# tile # tile
if tag == (8, 10): if tag == (8, 10):

View File

@ -505,13 +505,13 @@ def _getmp(self):
file_contents.seek(info.next) file_contents.seek(info.next)
info.load(file_contents) info.load(file_contents)
mp = dict(info) mp = dict(info)
except Exception: except Exception as e:
raise SyntaxError("malformed MP Index (unreadable directory)") raise SyntaxError("malformed MP Index (unreadable directory)") from e
# it's an error not to have a number of images # it's an error not to have a number of images
try: try:
quant = mp[0xB001] quant = mp[0xB001]
except KeyError: except KeyError as e:
raise SyntaxError("malformed MP Index (no number of images)") raise SyntaxError("malformed MP Index (no number of images)") from e
# get MP entries # get MP entries
mpentries = [] mpentries = []
try: try:
@ -547,8 +547,8 @@ def _getmp(self):
mpentry["Attribute"] = mpentryattr mpentry["Attribute"] = mpentryattr
mpentries.append(mpentry) mpentries.append(mpentry)
mp[0xB002] = mpentries mp[0xB002] = mpentries
except KeyError: except KeyError as e:
raise SyntaxError("malformed MP Index (bad MP Entry)") raise SyntaxError("malformed MP Index (bad MP Entry)") from e
# Next we should try and parse the individual image unique ID list; # Next we should try and parse the individual image unique ID list;
# we don't because I've never seen this actually used in a real MPO # we don't because I've never seen this actually used in a real MPO
# file and so can't test it. # file and so can't test it.
@ -612,8 +612,8 @@ def _save(im, fp, filename):
try: try:
rawmode = RAWMODE[im.mode] rawmode = RAWMODE[im.mode]
except KeyError: except KeyError as e:
raise OSError("cannot write mode %s as JPEG" % im.mode) raise OSError("cannot write mode %s as JPEG" % im.mode) from e
info = im.encoderinfo info = im.encoderinfo
@ -665,8 +665,8 @@ def _save(im, fp, filename):
for line in qtables.splitlines() for line in qtables.splitlines()
for num in line.split("#", 1)[0].split() for num in line.split("#", 1)[0].split()
] ]
except ValueError: except ValueError as e:
raise ValueError("Invalid quantization table") raise ValueError("Invalid quantization table") from e
else: else:
qtables = [lines[s : s + 64] for s in range(0, len(lines), 64)] qtables = [lines[s : s + 64] for s in range(0, len(lines), 64)]
if isinstance(qtables, (tuple, list, dict)): if isinstance(qtables, (tuple, list, dict)):
@ -681,8 +681,8 @@ def _save(im, fp, filename):
if len(table) != 64: if len(table) != 64:
raise TypeError raise TypeError
table = array.array("B", table) table = array.array("B", table)
except TypeError: except TypeError as e:
raise ValueError("Invalid quantization table") raise ValueError("Invalid quantization table") from e
else: else:
qtables[idx] = list(table) qtables[idx] = list(table)
return qtables return qtables

View File

@ -46,8 +46,8 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
try: try:
self.ole = olefile.OleFileIO(self.fp) self.ole = olefile.OleFileIO(self.fp)
except OSError: except OSError as e:
raise SyntaxError("not an MIC file; invalid OLE file") raise SyntaxError("not an MIC file; invalid OLE file") from e
# find ACI subfiles with Image members (maybe not the # find ACI subfiles with Image members (maybe not the
# best way to identify MIC files, but what the... ;-) # best way to identify MIC files, but what the... ;-)
@ -77,8 +77,8 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
return return
try: try:
filename = self.images[frame] filename = self.images[frame]
except IndexError: except IndexError as e:
raise EOFError("no such frame") raise EOFError("no such frame") from e
self.fp = self.ole.openstream(filename) self.fp = self.ole.openstream(filename)

View File

@ -116,8 +116,8 @@ class MspDecoder(ImageFile.PyDecoder):
rowmap = struct.unpack_from( rowmap = struct.unpack_from(
"<%dH" % (self.state.ysize), self.fd.read(self.state.ysize * 2) "<%dH" % (self.state.ysize), self.fd.read(self.state.ysize * 2)
) )
except struct.error: except struct.error as e:
raise OSError("Truncated MSP file in row map") raise OSError("Truncated MSP file in row map") from e
for x, rowlen in enumerate(rowmap): for x, rowlen in enumerate(rowmap):
try: try:
@ -142,8 +142,8 @@ class MspDecoder(ImageFile.PyDecoder):
img.write(row[idx : idx + runcount]) img.write(row[idx : idx + runcount])
idx += runcount idx += runcount
except struct.error: except struct.error as e:
raise OSError("Corrupted MSP file in row %d" % x) raise OSError("Corrupted MSP file in row %d" % x) from e
self.set_as_raw(img.getvalue(), ("1", 0, 1)) self.set_as_raw(img.getvalue(), ("1", 0, 1))

View File

@ -131,8 +131,8 @@ def _save(im, fp, filename):
try: try:
version, bits, planes, rawmode = SAVE[im.mode] version, bits, planes, rawmode = SAVE[im.mode]
except KeyError: except KeyError as e:
raise ValueError("Cannot save %s images as PCX" % im.mode) raise ValueError("Cannot save %s images as PCX" % im.mode) from e
# bytes per plane # bytes per plane
stride = (im.size[0] * bits + 7) // 8 stride = (im.size[0] * bits + 7) // 8

View File

@ -168,8 +168,10 @@ class ChunkStream:
crc2 = i32(self.fp.read(4)) crc2 = i32(self.fp.read(4))
if crc1 != crc2: if crc1 != crc2:
raise SyntaxError("broken PNG file (bad header checksum in %r)" % cid) raise SyntaxError("broken PNG file (bad header checksum in %r)" % cid)
except struct.error: except struct.error as e:
raise SyntaxError("broken PNG file (incomplete checksum in %r)" % cid) raise SyntaxError(
"broken PNG file (incomplete checksum in %r)" % cid
) from e
def crc_skip(self, cid, data): def crc_skip(self, cid, data):
"""Read checksum. Used if the C module is not present""" """Read checksum. Used if the C module is not present"""
@ -186,8 +188,8 @@ class ChunkStream:
while True: while True:
try: try:
cid, pos, length = self.read() cid, pos, length = self.read()
except struct.error: except struct.error as e:
raise OSError("truncated PNG file") raise OSError("truncated PNG file") from e
if cid == endchunk: if cid == endchunk:
break break
@ -737,9 +739,9 @@ class PngImageFile(ImageFile.ImageFile):
for f in range(self.__frame + 1, frame + 1): for f in range(self.__frame + 1, frame + 1):
try: try:
self._seek(f) self._seek(f)
except EOFError: except EOFError as e:
self.seek(last_frame) self.seek(last_frame)
raise EOFError("no more images in APNG file") raise EOFError("no more images in APNG file") from e
def _seek(self, frame, rewind=False): def _seek(self, frame, rewind=False):
if frame == 0: if frame == 0:
@ -1168,8 +1170,8 @@ def _save(im, fp, filename, chunk=putchunk, save_all=False):
# get the corresponding PNG mode # get the corresponding PNG mode
try: try:
rawmode, mode = _OUTMODES[mode] rawmode, mode = _OUTMODES[mode]
except KeyError: except KeyError as e:
raise OSError("cannot write mode %s as PNG" % mode) raise OSError("cannot write mode %s as PNG" % mode) from e
# #
# write minimal PNG file # write minimal PNG file

View File

@ -144,8 +144,8 @@ class PsdImageFile(ImageFile.ImageFile):
self.frame = layer self.frame = layer
self.fp = self.__fp self.fp = self.__fp
return name, bbox return name, bbox
except IndexError: except IndexError as e:
raise EOFError("no such layer") raise EOFError("no such layer") from e
def tell(self): def tell(self):
# return layer number (0=image, 1..max=layers) # return layer number (0=image, 1..max=layers)

View File

@ -111,8 +111,8 @@ class SpiderImageFile(ImageFile.ImageFile):
hdrlen = isSpiderHeader(t) hdrlen = isSpiderHeader(t)
if hdrlen == 0: if hdrlen == 0:
raise SyntaxError("not a valid Spider file") raise SyntaxError("not a valid Spider file")
except struct.error: except struct.error as e:
raise SyntaxError("not a valid Spider file") raise SyntaxError("not a valid Spider file") from e
h = (99,) + t # add 1 value : spider header index starts at 1 h = (99,) + t # add 1 value : spider header index starts at 1
iform = int(h[5]) iform = int(h[5])

View File

@ -167,8 +167,8 @@ def _save(im, fp, filename):
try: try:
rawmode, bits, colormaptype, imagetype = SAVE[im.mode] rawmode, bits, colormaptype, imagetype = SAVE[im.mode]
except KeyError: except KeyError as e:
raise OSError("cannot write mode %s as TGA" % im.mode) raise OSError("cannot write mode %s as TGA" % im.mode) from e
if "rle" in im.encoderinfo: if "rle" in im.encoderinfo:
rle = im.encoderinfo["rle"] rle = im.encoderinfo["rle"]

View File

@ -1117,8 +1117,8 @@ class TiffImageFile(ImageFile.ImageFile):
) )
try: try:
decoder.setimage(self.im, extents) decoder.setimage(self.im, extents)
except ValueError: except ValueError as e:
raise OSError("Couldn't set the image") raise OSError("Couldn't set the image") from e
close_self_fp = self._exclusive_fp and not self.is_animated close_self_fp = self._exclusive_fp and not self.is_animated
if hasattr(self.fp, "getvalue"): if hasattr(self.fp, "getvalue"):
@ -1231,9 +1231,9 @@ class TiffImageFile(ImageFile.ImageFile):
logger.debug("format key: {}".format(key)) logger.debug("format key: {}".format(key))
try: try:
self.mode, rawmode = OPEN_INFO[key] self.mode, rawmode = OPEN_INFO[key]
except KeyError: except KeyError as e:
logger.debug("- unsupported format") logger.debug("- unsupported format")
raise SyntaxError("unknown pixel mode") raise SyntaxError("unknown pixel mode") from e
logger.debug("- raw mode: {}".format(rawmode)) logger.debug("- raw mode: {}".format(rawmode))
logger.debug("- pil mode: {}".format(self.mode)) logger.debug("- pil mode: {}".format(self.mode))
@ -1400,8 +1400,8 @@ def _save(im, fp, filename):
try: try:
rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode] rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode]
except KeyError: except KeyError as e:
raise OSError("cannot write mode %s as TIFF" % im.mode) raise OSError("cannot write mode %s as TIFF" % im.mode) from e
ifd = ImageFileDirectory_v2(prefix=prefix) ifd = ImageFileDirectory_v2(prefix=prefix)