diff --git a/Tests/test_file_jpeg2k.py b/Tests/test_file_jpeg2k.py index a5365a90d44..575d911def5 100644 --- a/Tests/test_file_jpeg2k.py +++ b/Tests/test_file_jpeg2k.py @@ -164,7 +164,7 @@ def test_reduce() -> None: with Image.open("Tests/images/test-card-lossless.jp2") as im: assert callable(im.reduce) - im.reduce = 2 + im.reduce = 2 # type: ignore[assignment, method-assign] assert im.reduce == 2 im.load() diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py index e9830cd3dad..ed3a91285db 100644 --- a/Tests/test_file_png.py +++ b/Tests/test_file_png.py @@ -823,7 +823,7 @@ class MyStdOut: monkeypatch.setattr(sys, "stdout", mystdout) with Image.open(TEST_PNG_FILE) as im: - im.save(sys.stdout, "PNG") + im.save(sys.stdout, "PNG") # type: ignore[arg-type] if isinstance(mystdout, MyStdOut): mystdout = mystdout.buffer diff --git a/Tests/test_file_ppm.py b/Tests/test_file_ppm.py index 598e9a445b6..fbca46be513 100644 --- a/Tests/test_file_ppm.py +++ b/Tests/test_file_ppm.py @@ -389,7 +389,7 @@ class MyStdOut: monkeypatch.setattr(sys, "stdout", mystdout) with Image.open(TEST_FILE) as im: - im.save(sys.stdout, "PPM") + im.save(sys.stdout, "PPM") # type: ignore[arg-type] if isinstance(mystdout, MyStdOut): mystdout = mystdout.buffer diff --git a/Tests/test_image_transform.py b/Tests/test_image_transform.py index 7cf52ddbabe..3e2b9fee8ed 100644 --- a/Tests/test_image_transform.py +++ b/Tests/test_image_transform.py @@ -250,14 +250,14 @@ def test_blank_fill(self) -> None: def test_missing_method_data(self) -> None: with hopper() as im: with pytest.raises(ValueError): - im.transform((100, 100), None) + im.transform((100, 100), None) # type: ignore[arg-type] @pytest.mark.parametrize("resample", (Image.Resampling.BOX, "unknown")) def test_unknown_resampling_filter(self, resample: Image.Resampling | str) -> None: with hopper() as im: (w, h) = im.size with pytest.raises(ValueError): - im.transform((100, 100), Image.Transform.EXTENT, (0, 0, w, h), resample) + im.transform((100, 100), Image.Transform.EXTENT, (0, 0, w, h), resample) # type: ignore[arg-type] class TestImageTransformAffine: diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 4e61900f6fd..b4de099be53 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -590,16 +590,11 @@ def _new(self, im: core.ImagingCore) -> Image: return new # Context manager support - def __enter__(self): + def __enter__(self) -> Image: return self - def __exit__(self, *args): - from . import ImageFile - - if isinstance(self, ImageFile.ImageFile): - if getattr(self, "_exclusive_fp", False): - self._close_fp() - self.fp = None + def __exit__(self, *args: object) -> None: + pass def close(self) -> None: """ diff --git a/src/PIL/ImageFile.py b/src/PIL/ImageFile.py index f609c7d13c2..3390dfa97dd 100644 --- a/src/PIL/ImageFile.py +++ b/src/PIL/ImageFile.py @@ -131,6 +131,7 @@ def __init__( self.decoderconfig: tuple[Any, ...] = () self.decodermaxblock = MAXBLOCK + self.fp: IO[bytes] | None self._fp: IO[bytes] | DeferredError if is_path(fp): # filename @@ -168,6 +169,10 @@ def __init__( def _open(self) -> None: pass + # Context manager support + def __enter__(self) -> ImageFile: + return self + def _close_fp(self) -> None: if getattr(self, "_fp", False) and not isinstance(self._fp, DeferredError): if self._fp != self.fp: @@ -176,6 +181,11 @@ def _close_fp(self) -> None: if self.fp: self.fp.close() + def __exit__(self, *args: object) -> None: + if getattr(self, "_exclusive_fp", False): + self._close_fp() + self.fp = None + def close(self) -> None: """ Closes the file pointer, if possible. @@ -268,7 +278,7 @@ def verify(self) -> None: # raise exception if something's wrong. must be called # directly after open, and closes file when finished. - if self._exclusive_fp: + if self._exclusive_fp and self.fp: self.fp.close() self.fp = None