diff --git a/Tests/test_file_jpeg.py b/Tests/test_file_jpeg.py index affc18625..cde951395 100644 --- a/Tests/test_file_jpeg.py +++ b/Tests/test_file_jpeg.py @@ -1011,7 +1011,9 @@ class TestFileJpeg: # Even though this decoder never says that it is finished # the image should still end when there is no new data class InfiniteMockPyDecoder(ImageFile.PyDecoder): - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode( + self, buffer: bytes | Image.SupportsArrayInterface + ) -> tuple[int, int]: return 0, 0 Image.register_decoder("INFINITE", InfiniteMockPyDecoder) diff --git a/Tests/test_imagefile.py b/Tests/test_imagefile.py index 0985dce9c..1ee684926 100644 --- a/Tests/test_imagefile.py +++ b/Tests/test_imagefile.py @@ -210,7 +210,7 @@ class MockPyDecoder(ImageFile.PyDecoder): super().__init__(mode, *args) - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: # eof return -1, 0 diff --git a/docs/example/DdsImagePlugin.py b/docs/example/DdsImagePlugin.py index d8f536076..10828bff0 100644 --- a/docs/example/DdsImagePlugin.py +++ b/docs/example/DdsImagePlugin.py @@ -257,7 +257,7 @@ class DdsImageFile(ImageFile.ImageFile): class DXT1Decoder(ImageFile.PyDecoder): _pulls_fd = True - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: assert self.fd is not None try: self.set_as_raw(_dxt1(self.fd, self.state.xsize, self.state.ysize)) @@ -270,7 +270,7 @@ class DXT1Decoder(ImageFile.PyDecoder): class DXT5Decoder(ImageFile.PyDecoder): _pulls_fd = True - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: assert self.fd is not None try: self.set_as_raw(_dxt5(self.fd, self.state.xsize, self.state.ysize)) diff --git a/src/PIL/BlpImagePlugin.py b/src/PIL/BlpImagePlugin.py index 8e29898df..e5605635e 100644 --- a/src/PIL/BlpImagePlugin.py +++ b/src/PIL/BlpImagePlugin.py @@ -279,7 +279,7 @@ class BlpImageFile(ImageFile.ImageFile): class _BLPBaseDecoder(ImageFile.PyDecoder): _pulls_fd = True - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: try: self._read_blp_header() self._load() diff --git a/src/PIL/BmpImagePlugin.py b/src/PIL/BmpImagePlugin.py index 16c8cf6ff..bf8f29577 100644 --- a/src/PIL/BmpImagePlugin.py +++ b/src/PIL/BmpImagePlugin.py @@ -321,7 +321,7 @@ class BmpImageFile(ImageFile.ImageFile): class BmpRleDecoder(ImageFile.PyDecoder): _pulls_fd = True - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: assert self.fd is not None rle4 = self.args[1] data = bytearray() diff --git a/src/PIL/DdsImagePlugin.py b/src/PIL/DdsImagePlugin.py index 631532470..1b6408237 100644 --- a/src/PIL/DdsImagePlugin.py +++ b/src/PIL/DdsImagePlugin.py @@ -481,7 +481,7 @@ class DdsImageFile(ImageFile.ImageFile): class DdsRgbDecoder(ImageFile.PyDecoder): _pulls_fd = True - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: assert self.fd is not None bitcount, masks = self.args diff --git a/src/PIL/FitsImagePlugin.py b/src/PIL/FitsImagePlugin.py index abacc5e67..6bbd2641a 100644 --- a/src/PIL/FitsImagePlugin.py +++ b/src/PIL/FitsImagePlugin.py @@ -126,7 +126,7 @@ class FitsImageFile(ImageFile.ImageFile): class FitsGzipDecoder(ImageFile.PyDecoder): _pulls_fd = True - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: assert self.fd is not None value = gzip.decompress(self.fd.read()) diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 1c0cf2936..90d028b9b 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -856,7 +856,10 @@ class Image: ) def frombytes( - self, data: bytes | bytearray, decoder_name: str = "raw", *args: Any + self, + data: bytes | bytearray | SupportsArrayInterface, + decoder_name: str = "raw", + *args: Any, ) -> None: """ Loads this image with pixel data from a bytes object. @@ -3145,7 +3148,7 @@ def new( def frombytes( mode: str, size: tuple[int, int], - data: bytes | bytearray, + data: bytes | bytearray | SupportsArrayInterface, decoder_name: str = "raw", *args: Any, ) -> Image: @@ -3189,7 +3192,11 @@ def frombytes( def frombuffer( - mode: str, size: tuple[int, int], data, decoder_name: str = "raw", *args: Any + mode: str, + size: tuple[int, int], + data: bytes | SupportsArrayInterface, + decoder_name: str = "raw", + *args: Any, ) -> Image: """ Creates an image memory referencing pixel data in a byte buffer. diff --git a/src/PIL/ImageFile.py b/src/PIL/ImageFile.py index 615961ce5..b8bf0b7fe 100644 --- a/src/PIL/ImageFile.py +++ b/src/PIL/ImageFile.py @@ -733,7 +733,7 @@ class PyDecoder(PyCodec): def pulls_fd(self) -> bool: return self._pulls_fd - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: """ Override to perform the decoding process. diff --git a/src/PIL/MspImagePlugin.py b/src/PIL/MspImagePlugin.py index 1363ddd1f..f3460a787 100644 --- a/src/PIL/MspImagePlugin.py +++ b/src/PIL/MspImagePlugin.py @@ -112,7 +112,7 @@ class MspDecoder(ImageFile.PyDecoder): _pulls_fd = True - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: assert self.fd is not None img = io.BytesIO() diff --git a/src/PIL/PpmImagePlugin.py b/src/PIL/PpmImagePlugin.py index 3bda2bf28..4e779df17 100644 --- a/src/PIL/PpmImagePlugin.py +++ b/src/PIL/PpmImagePlugin.py @@ -284,7 +284,7 @@ class PpmPlainDecoder(ImageFile.PyDecoder): break return data - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: self._comment_spans = False if self.mode == "1": data = self._decode_bitonal() @@ -300,7 +300,7 @@ class PpmPlainDecoder(ImageFile.PyDecoder): class PpmDecoder(ImageFile.PyDecoder): _pulls_fd = True - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: assert self.fd is not None data = bytearray() diff --git a/src/PIL/QoiImagePlugin.py b/src/PIL/QoiImagePlugin.py index eaf031402..010d3f941 100644 --- a/src/PIL/QoiImagePlugin.py +++ b/src/PIL/QoiImagePlugin.py @@ -47,7 +47,7 @@ class QoiDecoder(ImageFile.PyDecoder): hash_value = (r * 3 + g * 5 + b * 7 + a * 11) % 64 self._previously_seen_pixels[hash_value] = value - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: assert self.fd is not None self._previously_seen_pixels = {} diff --git a/src/PIL/SgiImagePlugin.py b/src/PIL/SgiImagePlugin.py index 2c205a926..44254b7a4 100644 --- a/src/PIL/SgiImagePlugin.py +++ b/src/PIL/SgiImagePlugin.py @@ -214,7 +214,7 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: class SGI16Decoder(ImageFile.PyDecoder): _pulls_fd = True - def decode(self, buffer: bytes) -> tuple[int, int]: + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: assert self.fd is not None assert self.im is not None