mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-03 21:24:31 +03:00
Merge pull request #7609 from bgilbert/encoder-errors
Translate encoder error codes to strings; deprecate `ImageFile.raise_oserror()`
This commit is contained in:
commit
45e44085c0
|
@ -115,6 +115,7 @@ class TestImageFile:
|
||||||
assert_image_equal(im1, im2)
|
assert_image_equal(im1, im2)
|
||||||
|
|
||||||
def test_raise_oserror(self):
|
def test_raise_oserror(self):
|
||||||
|
with pytest.warns(DeprecationWarning):
|
||||||
with pytest.raises(OSError):
|
with pytest.raises(OSError):
|
||||||
ImageFile.raise_oserror(1)
|
ImageFile.raise_oserror(1)
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,16 @@ Since Pillow's C API is now faster than PyAccess on PyPy,
|
||||||
``Image.USE_CFFI_ACCESS``, for switching from the C API to PyAccess, is
|
``Image.USE_CFFI_ACCESS``, for switching from the C API to PyAccess, is
|
||||||
similarly deprecated.
|
similarly deprecated.
|
||||||
|
|
||||||
|
ImageFile.raise_oserror
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. deprecated:: 10.2.0
|
||||||
|
|
||||||
|
``ImageFile.raise_oserror()`` has been deprecated and will be removed in Pillow
|
||||||
|
12.0.0 (2025-10-15). The function is undocumented and is only useful for translating
|
||||||
|
error codes returned by a codec's ``decode()`` method, which ImageFile already does
|
||||||
|
automatically.
|
||||||
|
|
||||||
Removed features
|
Removed features
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,14 @@ TODO
|
||||||
Deprecations
|
Deprecations
|
||||||
============
|
============
|
||||||
|
|
||||||
|
ImageFile.raise_oserror
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
``ImageFile.raise_oserror()`` has been deprecated and will be removed in Pillow
|
||||||
|
12.0.0 (2025-10-15). The function is undocumented and is only useful for translating
|
||||||
|
error codes returned by a codec's ``decode()`` method, which ImageFile already does
|
||||||
|
automatically.
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
|
@ -77,3 +85,9 @@ Calculating the :py:attr:`~PIL.ImageStat.Stat.count` and
|
||||||
:py:attr:`~PIL.ImageStat.Stat.extrema` statistics is now faster. After the
|
:py:attr:`~PIL.ImageStat.Stat.extrema` statistics is now faster. After the
|
||||||
histogram is created in ``st = ImageStat.Stat(im)``, ``st.count`` is 3x as fast
|
histogram is created in ``st = ImageStat.Stat(im)``, ``st.count`` is 3x as fast
|
||||||
on average and ``st.extrema`` is 12x as fast on average.
|
on average and ``st.extrema`` is 12x as fast on average.
|
||||||
|
|
||||||
|
Encoder errors now report error detail as string
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
:py:exc:`OSError` exceptions from image encoders now include a textual description of
|
||||||
|
the error instead of a numeric error code.
|
||||||
|
|
|
@ -35,6 +35,7 @@ import sys
|
||||||
from typing import NamedTuple
|
from typing import NamedTuple
|
||||||
|
|
||||||
from . import Image
|
from . import Image
|
||||||
|
from ._deprecate import deprecate
|
||||||
from ._util import is_path
|
from ._util import is_path
|
||||||
|
|
||||||
MAXBLOCK = 65536
|
MAXBLOCK = 65536
|
||||||
|
@ -63,15 +64,25 @@ Dict of known error codes returned from :meth:`.PyDecoder.decode`,
|
||||||
# Helpers
|
# Helpers
|
||||||
|
|
||||||
|
|
||||||
def raise_oserror(error):
|
def _get_oserror(error, *, encoder):
|
||||||
try:
|
try:
|
||||||
msg = Image.core.getcodecstatus(error)
|
msg = Image.core.getcodecstatus(error)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
msg = ERRORS.get(error)
|
msg = ERRORS.get(error)
|
||||||
if not msg:
|
if not msg:
|
||||||
msg = f"decoder error {error}"
|
msg = f"{'encoder' if encoder else 'decoder'} error {error}"
|
||||||
msg += " when reading image file"
|
msg += f" when {'writing' if encoder else 'reading'} image file"
|
||||||
raise OSError(msg)
|
return OSError(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def raise_oserror(error):
|
||||||
|
deprecate(
|
||||||
|
"raise_oserror",
|
||||||
|
12,
|
||||||
|
action="It is only useful for translating error codes returned by a codec's "
|
||||||
|
"decode() method, which ImageFile already does automatically.",
|
||||||
|
)
|
||||||
|
raise _get_oserror(error, encoder=False)
|
||||||
|
|
||||||
|
|
||||||
def _tilesort(t):
|
def _tilesort(t):
|
||||||
|
@ -294,7 +305,7 @@ class ImageFile(Image.Image):
|
||||||
|
|
||||||
if not self.map and not LOAD_TRUNCATED_IMAGES and err_code < 0:
|
if not self.map and not LOAD_TRUNCATED_IMAGES and err_code < 0:
|
||||||
# still raised if decoder fails to return anything
|
# still raised if decoder fails to return anything
|
||||||
raise_oserror(err_code)
|
raise _get_oserror(err_code, encoder=False)
|
||||||
|
|
||||||
return Image.Image.load(self)
|
return Image.Image.load(self)
|
||||||
|
|
||||||
|
@ -421,7 +432,7 @@ class Parser:
|
||||||
if e < 0:
|
if e < 0:
|
||||||
# decoding error
|
# decoding error
|
||||||
self.image = None
|
self.image = None
|
||||||
raise_oserror(e)
|
raise _get_oserror(e, encoder=False)
|
||||||
else:
|
else:
|
||||||
# end of image
|
# end of image
|
||||||
return
|
return
|
||||||
|
@ -551,8 +562,7 @@ def _encode_tile(im, fp, tile: list[_Tile], bufsize, fh, exc=None):
|
||||||
# slight speedup: compress to real file object
|
# slight speedup: compress to real file object
|
||||||
errcode = encoder.encode_to_file(fh, bufsize)
|
errcode = encoder.encode_to_file(fh, bufsize)
|
||||||
if errcode < 0:
|
if errcode < 0:
|
||||||
msg = f"encoder error {errcode} when writing image file"
|
raise _get_oserror(errcode, encoder=True) from exc
|
||||||
raise OSError(msg) from exc
|
|
||||||
finally:
|
finally:
|
||||||
encoder.cleanup()
|
encoder.cleanup()
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@ def deprecate(
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
elif when == 11:
|
elif when == 11:
|
||||||
removed = "Pillow 11 (2024-10-15)"
|
removed = "Pillow 11 (2024-10-15)"
|
||||||
|
elif when == 12:
|
||||||
|
removed = "Pillow 12 (2025-10-15)"
|
||||||
else:
|
else:
|
||||||
msg = f"Unknown removal version: {when}. Update {__name__}?"
|
msg = f"Unknown removal version: {when}. Update {__name__}?"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user