Merge pull request #8042 from radarhere/type_hint

This commit is contained in:
Hugo van Kemenade 2024-05-09 17:38:46 +03:00 committed by GitHub
commit 0cad346fc9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 67 additions and 62 deletions

View File

@ -253,7 +253,7 @@ class BlpImageFile(ImageFile.ImageFile):
format = "BLP" format = "BLP"
format_description = "Blizzard Mipmap Format" format_description = "Blizzard Mipmap Format"
def _open(self): def _open(self) -> None:
self.magic = self.fp.read(4) self.magic = self.fp.read(4)
self.fp.seek(5, os.SEEK_CUR) self.fp.seek(5, os.SEEK_CUR)
@ -333,7 +333,7 @@ class _BLPBaseDecoder(ImageFile.PyDecoder):
class BLP1Decoder(_BLPBaseDecoder): class BLP1Decoder(_BLPBaseDecoder):
def _load(self): def _load(self) -> None:
if self._blp_compression == Format.JPEG: if self._blp_compression == Format.JPEG:
self._decode_jpeg_stream() self._decode_jpeg_stream()
@ -418,7 +418,7 @@ class BLP2Decoder(_BLPBaseDecoder):
class BLPEncoder(ImageFile.PyEncoder): class BLPEncoder(ImageFile.PyEncoder):
_pushes_fd = True _pushes_fd = True
def _write_palette(self): def _write_palette(self) -> bytes:
data = b"" data = b""
palette = self.im.getpalette("RGBA", "RGBA") palette = self.im.getpalette("RGBA", "RGBA")
for i in range(len(palette) // 4): for i in range(len(palette) // 4):

View File

@ -283,7 +283,7 @@ class BmpImageFile(ImageFile.ImageFile):
) )
] ]
def _open(self): def _open(self) -> None:
"""Open file, check magic number and read header""" """Open file, check magic number and read header"""
# read 14 bytes: magic number, filesize, reserved, header final offset # read 14 bytes: magic number, filesize, reserved, header final offset
head_data = self.fp.read(14) head_data = self.fp.read(14)
@ -376,7 +376,7 @@ class DibImageFile(BmpImageFile):
format = "DIB" format = "DIB"
format_description = "Windows Bitmap" format_description = "Windows Bitmap"
def _open(self): def _open(self) -> None:
self._bitmap() self._bitmap()

View File

@ -63,7 +63,7 @@ class DcxImageFile(PcxImageFile):
self.is_animated = self.n_frames > 1 self.is_animated = self.n_frames > 1
self.seek(0) self.seek(0)
def seek(self, frame): def seek(self, frame: int) -> None:
if not self._seek_check(frame): if not self._seek_check(frame):
return return
self.frame = frame self.frame = frame
@ -71,7 +71,7 @@ class DcxImageFile(PcxImageFile):
self.fp.seek(self._offset[frame]) self.fp.seek(self._offset[frame])
PcxImageFile._open(self) PcxImageFile._open(self)
def tell(self): def tell(self) -> int:
return self.frame return self.frame

View File

@ -331,7 +331,7 @@ class DdsImageFile(ImageFile.ImageFile):
format = "DDS" format = "DDS"
format_description = "DirectDraw Surface" format_description = "DirectDraw Surface"
def _open(self): def _open(self) -> None:
if not _accept(self.fp.read(4)): if not _accept(self.fp.read(4)):
msg = "not a DDS file" msg = "not a DDS file"
raise SyntaxError(msg) raise SyntaxError(msg)

View File

@ -178,7 +178,7 @@ class PSFile:
self.char = None self.char = None
self.fp.seek(offset, whence) self.fp.seek(offset, whence)
def readline(self): def readline(self) -> str:
s = [self.char or b""] s = [self.char or b""]
self.char = None self.char = None
@ -212,7 +212,7 @@ class EpsImageFile(ImageFile.ImageFile):
mode_map = {1: "L", 2: "LAB", 3: "RGB", 4: "CMYK"} mode_map = {1: "L", 2: "LAB", 3: "RGB", 4: "CMYK"}
def _open(self): def _open(self) -> None:
(length, offset) = self._find_offset(self.fp) (length, offset) = self._find_offset(self.fp)
# go to offset - start of "%!PS" # go to offset - start of "%!PS"

View File

@ -123,7 +123,7 @@ class FliImageFile(ImageFile.ImageFile):
palette[i] = (r, g, b) palette[i] = (r, g, b)
i += 1 i += 1
def seek(self, frame): def seek(self, frame: int) -> None:
if not self._seek_check(frame): if not self._seek_check(frame):
return return
if frame < self.__frame: if frame < self.__frame:
@ -162,7 +162,7 @@ class FliImageFile(ImageFile.ImageFile):
self.__offset += framesize self.__offset += framesize
def tell(self): def tell(self) -> int:
return self.__frame return self.__frame

View File

@ -76,7 +76,7 @@ class GifImageFile(ImageFile.ImageFile):
global_palette = None global_palette = None
def data(self): def data(self) -> bytes | None:
s = self.fp.read(1) s = self.fp.read(1)
if s and s[0]: if s and s[0]:
return self.fp.read(s[0]) return self.fp.read(s[0])
@ -88,7 +88,7 @@ class GifImageFile(ImageFile.ImageFile):
return True return True
return False return False
def _open(self): def _open(self) -> None:
# Screen # Screen
s = self.fp.read(13) s = self.fp.read(13)
if not _accept(s): if not _accept(s):
@ -147,7 +147,7 @@ class GifImageFile(ImageFile.ImageFile):
self.seek(current) self.seek(current)
return self._is_animated return self._is_animated
def seek(self, frame): def seek(self, frame: int) -> None:
if not self._seek_check(frame): if not self._seek_check(frame):
return return
if frame < self.__frame: if frame < self.__frame:
@ -417,7 +417,7 @@ class GifImageFile(ImageFile.ImageFile):
elif k in self.info: elif k in self.info:
del self.info[k] del self.info[k]
def load_prepare(self): def load_prepare(self) -> None:
temp_mode = "P" if self._frame_palette else "L" temp_mode = "P" if self._frame_palette else "L"
self._prev_im = None self._prev_im = None
if self.__frame == 0: if self.__frame == 0:
@ -437,7 +437,7 @@ class GifImageFile(ImageFile.ImageFile):
super().load_prepare() super().load_prepare()
def load_end(self): def load_end(self) -> None:
if self.__frame == 0: if self.__frame == 0:
if self.mode == "P" and LOADING_STRATEGY == LoadingStrategy.RGB_ALWAYS: if self.mode == "P" and LOADING_STRATEGY == LoadingStrategy.RGB_ALWAYS:
if self._frame_transparency is not None: if self._frame_transparency is not None:
@ -463,7 +463,7 @@ class GifImageFile(ImageFile.ImageFile):
else: else:
self.im.paste(frame_im, self.dispose_extent) self.im.paste(frame_im, self.dispose_extent)
def tell(self): def tell(self) -> int:
return self.__frame return self.__frame

View File

@ -37,7 +37,7 @@ class HDF5StubImageFile(ImageFile.StubImageFile):
format = "HDF5" format = "HDF5"
format_description = "HDF5" format_description = "HDF5"
def _open(self): def _open(self) -> None:
offset = self.fp.tell() offset = self.fp.tell()
if not _accept(self.fp.read(8)): if not _accept(self.fp.read(8)):

View File

@ -252,7 +252,7 @@ class IcnsImageFile(ImageFile.ImageFile):
format = "ICNS" format = "ICNS"
format_description = "Mac OS icns resource" format_description = "Mac OS icns resource"
def _open(self): def _open(self) -> None:
self.icns = IcnsFile(self.fp) self.icns = IcnsFile(self.fp)
self._mode = "RGBA" self._mode = "RGBA"
self.info["sizes"] = self.icns.itersizes() self.info["sizes"] = self.icns.itersizes()

View File

@ -302,7 +302,7 @@ class IcoImageFile(ImageFile.ImageFile):
format = "ICO" format = "ICO"
format_description = "Windows Icon" format_description = "Windows Icon"
def _open(self): def _open(self) -> None:
self.ico = IcoFile(self.fp) self.ico = IcoFile(self.fp)
self.info["sizes"] = self.ico.sizes() self.info["sizes"] = self.ico.sizes()
self.size = self.ico.entry[0]["dim"] self.size = self.ico.entry[0]["dim"]

View File

@ -278,7 +278,7 @@ class ImImageFile(ImageFile.ImageFile):
def is_animated(self): def is_animated(self):
return self.info[FRAMES] > 1 return self.info[FRAMES] > 1
def seek(self, frame): def seek(self, frame: int) -> None:
if not self._seek_check(frame): if not self._seek_check(frame):
return return
@ -296,7 +296,7 @@ class ImImageFile(ImageFile.ImageFile):
self.tile = [("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1))] self.tile = [("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1))]
def tell(self): def tell(self) -> int:
return self.frame return self.frame

View File

@ -1298,7 +1298,10 @@ class Image:
self.load() self.load()
return self._new(self.im.expand(xmargin, ymargin)) return self._new(self.im.expand(xmargin, ymargin))
def filter(self, filter): if TYPE_CHECKING:
from . import ImageFilter
def filter(self, filter: ImageFilter.Filter | type[ImageFilter.Filter]) -> Image:
""" """
Filters this image using the given filter. For a list of Filters this image using the given filter. For a list of
available filters, see the :py:mod:`~PIL.ImageFilter` module. available filters, see the :py:mod:`~PIL.ImageFilter` module.
@ -1310,7 +1313,7 @@ class Image:
self.load() self.load()
if isinstance(filter, Callable): if callable(filter):
filter = filter() filter = filter()
if not hasattr(filter, "filter"): if not hasattr(filter, "filter"):
msg = "filter argument should be ImageFilter.Filter instance or class" msg = "filter argument should be ImageFilter.Filter instance or class"

View File

@ -311,7 +311,7 @@ class ImageFile(Image.Image):
return Image.Image.load(self) return Image.Image.load(self)
def load_prepare(self): def load_prepare(self) -> None:
# create image memory if necessary # create image memory if necessary
if not self.im or self.im.mode != self.mode or self.im.size != self.size: if not self.im or self.im.mode != self.mode or self.im.size != self.size:
self.im = Image.core.new(self.mode, self.size) self.im = Image.core.new(self.mode, self.size)
@ -319,7 +319,7 @@ class ImageFile(Image.Image):
if self.mode == "P": if self.mode == "P":
Image.Image.load(self) Image.Image.load(self)
def load_end(self): def load_end(self) -> None:
# may be overridden # may be overridden
pass pass
@ -390,7 +390,7 @@ class Parser:
offset = 0 offset = 0
finished = 0 finished = 0
def reset(self): def reset(self) -> None:
""" """
(Consumer) Reset the parser. Note that you can only call this (Consumer) Reset the parser. Note that you can only call this
method immediately after you've created a parser; parser method immediately after you've created a parser; parser
@ -605,7 +605,7 @@ def _safe_read(fp, size):
class PyCodecState: class PyCodecState:
def __init__(self): def __init__(self) -> None:
self.xsize = 0 self.xsize = 0
self.ysize = 0 self.ysize = 0
self.xoff = 0 self.xoff = 0
@ -634,7 +634,7 @@ class PyCodec:
""" """
self.args = args self.args = args
def cleanup(self): def cleanup(self) -> None:
""" """
Override to perform codec specific cleanup Override to perform codec specific cleanup

View File

@ -16,10 +16,13 @@
# #
from __future__ import annotations from __future__ import annotations
import abc
import functools import functools
class Filter: class Filter:
@abc.abstractmethod
def filter(self, image):
pass pass

View File

@ -204,7 +204,7 @@ class Window:
def ui_handle_damage(self, x0, y0, x1, y1): def ui_handle_damage(self, x0, y0, x1, y1):
pass pass
def ui_handle_destroy(self): def ui_handle_destroy(self) -> None:
pass pass
def ui_handle_repair(self, dc, x0, y0, x1, y1): def ui_handle_repair(self, dc, x0, y0, x1, y1):
@ -213,7 +213,7 @@ class Window:
def ui_handle_resize(self, width, height): def ui_handle_resize(self, width, height):
pass pass
def mainloop(self): def mainloop(self) -> None:
Image.core.eventloop() Image.core.eventloop()

View File

@ -38,7 +38,7 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
format_description = "Microsoft Image Composer" format_description = "Microsoft Image Composer"
_close_exclusive_fp_after_loading = False _close_exclusive_fp_after_loading = False
def _open(self): def _open(self) -> None:
# read the OLE directory and see if this is a likely # read the OLE directory and see if this is a likely
# to be a Microsoft Image Composer file # to be a Microsoft Image Composer file
@ -88,7 +88,7 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
def tell(self): def tell(self):
return self.frame return self.frame
def close(self): def close(self) -> None:
self.__fp.close() self.__fp.close()
self.ole.close() self.ole.close()
super().close() super().close()

View File

@ -127,7 +127,7 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
def load_seek(self, pos): def load_seek(self, pos):
self._fp.seek(pos) self._fp.seek(pos)
def seek(self, frame): def seek(self, frame: int) -> None:
if not self._seek_check(frame): if not self._seek_check(frame):
return return
self.fp = self._fp self.fp = self._fp
@ -149,7 +149,7 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
self.tile = [("jpeg", (0, 0) + self.size, self.offset, self.tile[0][-1])] self.tile = [("jpeg", (0, 0) + self.size, self.offset, self.tile[0][-1])]
self.__frame = frame self.__frame = frame
def tell(self): def tell(self) -> int:
return self.__frame return self.__frame
@staticmethod @staticmethod

View File

@ -800,7 +800,7 @@ class PngImageFile(ImageFile.ImageFile):
self.fp.close() self.fp.close()
self.fp = None self.fp = None
def seek(self, frame): def seek(self, frame: int) -> None:
if not self._seek_check(frame): if not self._seek_check(frame):
return return
if frame < self.__frame: if frame < self.__frame:
@ -909,10 +909,10 @@ class PngImageFile(ImageFile.ImageFile):
else: else:
self.dispose = None self.dispose = None
def tell(self): def tell(self) -> int:
return self.__frame return self.__frame
def load_prepare(self): def load_prepare(self) -> None:
"""internal: prepare to read PNG file""" """internal: prepare to read PNG file"""
if self.info.get("interlace"): if self.info.get("interlace"):
@ -954,7 +954,7 @@ class PngImageFile(ImageFile.ImageFile):
return self.fp.read(read_bytes) return self.fp.read(read_bytes)
def load_end(self): def load_end(self) -> None:
"""internal: finished reading image data""" """internal: finished reading image data"""
if self.__idat != 0: if self.__idat != 0:
self.fp.read(self.__idat) self.fp.read(self.__idat)

View File

@ -57,7 +57,7 @@ class PsdImageFile(ImageFile.ImageFile):
format_description = "Adobe Photoshop" format_description = "Adobe Photoshop"
_close_exclusive_fp_after_loading = False _close_exclusive_fp_after_loading = False
def _open(self): def _open(self) -> None:
read = self.fp.read read = self.fp.read
# #
@ -141,23 +141,22 @@ class PsdImageFile(ImageFile.ImageFile):
self.frame = 1 self.frame = 1
self._min_frame = 1 self._min_frame = 1
def seek(self, layer): def seek(self, layer: int) -> None:
if not self._seek_check(layer): if not self._seek_check(layer):
return return
# seek to given layer (1..max) # seek to given layer (1..max)
try: try:
name, mode, bbox, tile = self.layers[layer - 1] _, mode, _, tile = self.layers[layer - 1]
self._mode = mode self._mode = mode
self.tile = tile self.tile = tile
self.frame = layer self.frame = layer
self.fp = self._fp self.fp = self._fp
return name, bbox
except IndexError as e: except IndexError as e:
msg = "no such layer" msg = "no such layer"
raise EOFError(msg) from e raise EOFError(msg) from e
def tell(self): def tell(self) -> int:
# return layer number (0=image, 1..max=layers) # return layer number (0=image, 1..max=layers)
return self.frame return self.frame

View File

@ -97,7 +97,7 @@ class SpiderImageFile(ImageFile.ImageFile):
format_description = "Spider 2D image" format_description = "Spider 2D image"
_close_exclusive_fp_after_loading = False _close_exclusive_fp_after_loading = False
def _open(self): def _open(self) -> None:
# check header # check header
n = 27 * 4 # read 27 float values n = 27 * 4 # read 27 float values
f = self.fp.read(n) f = self.fp.read(n)
@ -165,13 +165,13 @@ class SpiderImageFile(ImageFile.ImageFile):
return self._nimages > 1 return self._nimages > 1
# 1st image index is zero (although SPIDER imgnumber starts at 1) # 1st image index is zero (although SPIDER imgnumber starts at 1)
def tell(self): def tell(self) -> int:
if self.imgnumber < 1: if self.imgnumber < 1:
return 0 return 0
else: else:
return self.imgnumber - 1 return self.imgnumber - 1
def seek(self, frame): def seek(self, frame: int) -> None:
if self.istack == 0: if self.istack == 0:
msg = "attempt to seek in a non-stack file" msg = "attempt to seek in a non-stack file"
raise EOFError(msg) raise EOFError(msg)

View File

@ -1143,7 +1143,7 @@ class TiffImageFile(ImageFile.ImageFile):
self.seek(current) self.seek(current)
return self._n_frames return self._n_frames
def seek(self, frame): def seek(self, frame: int) -> None:
"""Select a given frame as current image""" """Select a given frame as current image"""
if not self._seek_check(frame): if not self._seek_check(frame):
return return
@ -1198,7 +1198,7 @@ class TiffImageFile(ImageFile.ImageFile):
self.__frame = frame self.__frame = frame
self._setup() self._setup()
def tell(self): def tell(self) -> int:
"""Return the current frame number""" """Return the current frame number"""
return self.__frame return self.__frame
@ -1237,7 +1237,7 @@ class TiffImageFile(ImageFile.ImageFile):
return self._load_libtiff() return self._load_libtiff()
return super().load() return super().load()
def load_end(self): def load_end(self) -> None:
# allow closing if we're on the first frame, there's no next # allow closing if we're on the first frame, there's no next
# This is the ImageFile.load path only, libtiff specific below. # This is the ImageFile.load path only, libtiff specific below.
if not self.is_animated: if not self.is_animated:
@ -1942,7 +1942,7 @@ class AppendingTiffWriter:
self.beginning = self.f.tell() self.beginning = self.f.tell()
self.setup() self.setup()
def setup(self): def setup(self) -> None:
# Reset everything. # Reset everything.
self.f.seek(self.beginning, os.SEEK_SET) self.f.seek(self.beginning, os.SEEK_SET)
@ -1967,7 +1967,7 @@ class AppendingTiffWriter:
self.skipIFDs() self.skipIFDs()
self.goToEnd() self.goToEnd()
def finalize(self): def finalize(self) -> None:
if self.isFirst: if self.isFirst:
return return
@ -1990,7 +1990,7 @@ class AppendingTiffWriter:
self.f.seek(ifd_offset) self.f.seek(ifd_offset)
self.fixIFD() self.fixIFD()
def newFrame(self): def newFrame(self) -> None:
# Call this to finish a frame. # Call this to finish a frame.
self.finalize() self.finalize()
self.setup() self.setup()
@ -2013,7 +2013,7 @@ class AppendingTiffWriter:
self.f.seek(offset, whence) self.f.seek(offset, whence)
return self.tell() return self.tell()
def goToEnd(self): def goToEnd(self) -> None:
self.f.seek(0, os.SEEK_END) self.f.seek(0, os.SEEK_END)
pos = self.f.tell() pos = self.f.tell()
@ -2029,7 +2029,7 @@ class AppendingTiffWriter:
self.shortFmt = f"{self.endian}H" self.shortFmt = f"{self.endian}H"
self.tagFormat = f"{self.endian}HHL" self.tagFormat = f"{self.endian}HHL"
def skipIFDs(self): def skipIFDs(self) -> None:
while True: while True:
ifd_offset = self.readLong() ifd_offset = self.readLong()
if ifd_offset == 0: if ifd_offset == 0:
@ -2084,11 +2084,11 @@ class AppendingTiffWriter:
msg = f"wrote only {bytes_written} bytes but wanted 4" msg = f"wrote only {bytes_written} bytes but wanted 4"
raise RuntimeError(msg) raise RuntimeError(msg)
def close(self): def close(self) -> None:
self.finalize() self.finalize()
self.f.close() self.f.close()
def fixIFD(self): def fixIFD(self) -> None:
num_tags = self.readShort() num_tags = self.readShort()
for i in range(num_tags): for i in range(num_tags):

View File

@ -32,7 +32,7 @@ class WalImageFile(ImageFile.ImageFile):
format = "WAL" format = "WAL"
format_description = "Quake2 Texture" format_description = "Quake2 Texture"
def _open(self): def _open(self) -> None:
self._mode = "P" self._mode = "P"
# read header fields # read header fields

View File

@ -109,7 +109,7 @@ class WebPImageFile(ImageFile.ImageFile):
""" """
return self._getxmp(self.info["xmp"]) if "xmp" in self.info else {} return self._getxmp(self.info["xmp"]) if "xmp" in self.info else {}
def seek(self, frame): def seek(self, frame: int) -> None:
if not self._seek_check(frame): if not self._seek_check(frame):
return return
@ -174,7 +174,7 @@ class WebPImageFile(ImageFile.ImageFile):
def load_seek(self, pos): def load_seek(self, pos):
pass pass
def tell(self): def tell(self) -> int:
if not _webp.HAVE_WEBPANIM: if not _webp.HAVE_WEBPANIM:
return super().tell() return super().tell()