diff --git a/Tests/test_image.py b/Tests/test_image.py index c5cf5b38331..93f9b9833ce 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -132,6 +132,15 @@ def test_open_formats(self) -> None: assert im.mode == "RGB" assert im.size == (128, 128) + def test_open_verbose_failure(self, monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setattr(Image, "WARN_POSSIBLE_FORMATS", True) + + im = io.BytesIO(b"") + with pytest.warns(UserWarning): + with pytest.raises(UnidentifiedImageError): + with Image.open(im): + pass + def test_width_height(self) -> None: im = Image.new("RGB", (1, 2)) assert im.width == 1 diff --git a/docs/reference/Image.rst b/docs/reference/Image.rst index e83c8787f0a..66c5e5422da 100644 --- a/docs/reference/Image.rst +++ b/docs/reference/Image.rst @@ -381,6 +381,11 @@ Constants Set to 89,478,485, approximately 0.25GB for a 24-bit (3 bpp) image. See :py:meth:`~PIL.Image.open` for more information about how this is used. +.. data:: WARN_POSSIBLE_FORMATS + + Set to false. If true, when an image cannot be identified, warnings will be raised + from formats that attempted to read the data. + Transpose methods ^^^^^^^^^^^^^^^^^ diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 970437e9a7b..d41c06523f4 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -85,6 +85,8 @@ class DecompressionBombError(Exception): pass +WARN_POSSIBLE_FORMATS: bool = False + # Limit to around a quarter gigabyte for a 24-bit (3 bpp) image MAX_IMAGE_PIXELS: int | None = int(1024 * 1024 * 1024 // 4 // 3) @@ -3441,7 +3443,7 @@ def open( preinit() - accept_warnings: list[str] = [] + warning_messages: list[str] = [] def _open_core( fp: IO[bytes], @@ -3457,17 +3459,15 @@ def _open_core( factory, accept = OPEN[i] result = not accept or accept(prefix) if isinstance(result, str): - accept_warnings.append(result) + warning_messages.append(result) elif result: fp.seek(0) im = factory(fp, filename) _decompression_bomb_check(im.size) return im - except (SyntaxError, IndexError, TypeError, struct.error): - # Leave disabled by default, spams the logs with image - # opening failures that are entirely expected. - # logger.debug("", exc_info=True) - continue + except (SyntaxError, IndexError, TypeError, struct.error) as e: + if WARN_POSSIBLE_FORMATS: + warning_messages.append(i + " opening failed. " + str(e)) except BaseException: if exclusive_fp: fp.close() @@ -3492,7 +3492,7 @@ def _open_core( if exclusive_fp: fp.close() - for message in accept_warnings: + for message in warning_messages: warnings.warn(message) msg = "cannot identify image file %r" % (filename if filename else fp) raise UnidentifiedImageError(msg)