diff --git a/Tests/test_image.py b/Tests/test_image.py index 742d0dfe406..a03e5eced07 100644 --- a/Tests/test_image.py +++ b/Tests/test_image.py @@ -116,6 +116,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 0d9b4d93d77..f25c9cd9d46 100644 --- a/docs/reference/Image.rst +++ b/docs/reference/Image.rst @@ -374,6 +374,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 958b95e3b0f..514a543c2d3 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -76,6 +76,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) @@ -3344,7 +3346,7 @@ def open( preinit() - accept_warnings: list[str] = [] + warning_messages: list[str] = [] def _open_core( fp: IO[bytes], @@ -3360,17 +3362,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() @@ -3395,7 +3395,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)