Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added type hints #8055

Merged
merged 1 commit into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/PIL/FliImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def seek(self, frame: int) -> None:
for f in range(self.__frame + 1, frame + 1):
self._seek(f)

def _seek(self, frame):
def _seek(self, frame: int) -> None:
if frame == 0:
self.__frame = -1
self._fp.seek(self.__rewind)
Expand Down
10 changes: 5 additions & 5 deletions src/PIL/GifImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def data(self) -> bytes | None:
return self.fp.read(s[0])
return None

def _is_palette_needed(self, p):
def _is_palette_needed(self, p: bytes) -> bool:
for i in range(0, len(p), 3):
if not (i // 3 == p[i] == p[i + 1] == p[i + 2]):
return True
Expand Down Expand Up @@ -474,7 +474,7 @@ def tell(self) -> int:
RAWMODE = {"1": "L", "L": "L", "P": "P"}


def _normalize_mode(im):
def _normalize_mode(im: Image.Image) -> Image.Image:
"""
Takes an image (or frame), returns an image in a mode that is appropriate
for saving in a Gif.
Expand Down Expand Up @@ -887,7 +887,7 @@ def _get_optimize(im, info):
return used_palette_colors


def _get_color_table_size(palette_bytes):
def _get_color_table_size(palette_bytes: bytes) -> int:
# calculate the palette size for the header
if not palette_bytes:
return 0
Expand All @@ -897,7 +897,7 @@ def _get_color_table_size(palette_bytes):
return math.ceil(math.log(len(palette_bytes) // 3, 2)) - 1


def _get_header_palette(palette_bytes):
def _get_header_palette(palette_bytes: bytes) -> bytes:
"""
Returns the palette, null padded to the next power of 2 (*3) bytes
suitable for direct inclusion in the GIF header
Expand All @@ -915,7 +915,7 @@ def _get_header_palette(palette_bytes):
return palette_bytes


def _get_palette_bytes(im):
def _get_palette_bytes(im: Image.Image) -> bytes:
"""
Gets the palette for inclusion in the gif header

Expand Down
2 changes: 1 addition & 1 deletion src/PIL/GimpPaletteFile.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@ def __init__(self, fp):

self.palette = b"".join(self.palette)

def getpalette(self):
def getpalette(self) -> tuple[bytes, str]:
return self.palette, self.rawmode
4 changes: 2 additions & 2 deletions src/PIL/ImImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,11 @@ def _open(self) -> None:
self.tile = [("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1))]

@property
def n_frames(self):
def n_frames(self) -> int:
return self.info[FRAMES]

@property
def is_animated(self):
def is_animated(self) -> bool:
return self.info[FRAMES] > 1

def seek(self, frame: int) -> None:
Expand Down
7 changes: 5 additions & 2 deletions src/PIL/ImageDraw.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import math
import numbers
import struct
from typing import Sequence, cast
from typing import TYPE_CHECKING, Sequence, cast

from . import Image, ImageColor
from ._typing import Coords
Expand Down Expand Up @@ -92,7 +92,10 @@ def __init__(self, im: Image.Image, mode: str | None = None) -> None:
self.fontmode = "L" # aliasing is okay for other modes
self.fill = False

def getfont(self):
if TYPE_CHECKING:
from . import ImageFont

def getfont(self) -> ImageFont.FreeTypeFont | ImageFont.ImageFont:
"""
Get the current default font.

Expand Down
2 changes: 1 addition & 1 deletion src/PIL/ImageFilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ def transform(self, callback, with_normals=False, channels=None, target_mode=Non
_copy_table=False,
)

def __repr__(self):
def __repr__(self) -> str:
r = [
f"{self.__class__.__name__} from {self.table.__class__.__name__}",
"size={:d}x{:d}x{:d}".format(*self.size),
Expand Down
6 changes: 3 additions & 3 deletions src/PIL/ImagePalette.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def colors(self):
def colors(self, colors):
self._colors = colors

def copy(self):
def copy(self) -> ImagePalette:
new = ImagePalette()

new.mode = self.mode
Expand All @@ -77,7 +77,7 @@ def copy(self):

return new

def getdata(self):
def getdata(self) -> tuple[str, bytes]:
"""
Get palette contents in format suitable for the low-level
``im.putpalette`` primitive.
Expand All @@ -88,7 +88,7 @@ def getdata(self):
return self.rawmode, self.palette
return self.mode, self.tobytes()

def tobytes(self):
def tobytes(self) -> bytes:
"""Convert palette to bytes.

.. warning:: This method is experimental.
Expand Down
12 changes: 6 additions & 6 deletions src/PIL/ImageTk.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def __del__(self) -> None:
except Exception:
pass # ignore internal errors

def __str__(self):
def __str__(self) -> str:
"""
Get the Tkinter photo image identifier. This method is automatically
called by Tkinter whenever a PhotoImage object is passed to a Tkinter
Expand All @@ -146,15 +146,15 @@ def __str__(self):
"""
return str(self.__photo)

def width(self):
def width(self) -> int:
"""
Get the width of the image.

:return: The width, in pixels.
"""
return self.__size[0]

def height(self):
def height(self) -> int:
"""
Get the height of the image.

Expand Down Expand Up @@ -227,23 +227,23 @@ def __del__(self) -> None:
except Exception:
pass # ignore internal errors

def width(self):
def width(self) -> int:
"""
Get the width of the image.

:return: The width, in pixels.
"""
return self.__size[0]

def height(self):
def height(self) -> int:
"""
Get the height of the image.

:return: The height, in pixels.
"""
return self.__size[1]

def __str__(self):
def __str__(self) -> str:
"""
Get the Tkinter bitmap image identifier. This method is automatically
called by Tkinter whenever a BitmapImage object is passed to a Tkinter
Expand Down
4 changes: 2 additions & 2 deletions src/PIL/Jpeg2KImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ def read_fields(self, field_format):
data = self._read_bytes(size)
return struct.unpack(field_format, data)

def read_boxes(self):
def read_boxes(self) -> BoxReader:
size = self.remaining_in_box
data = self._read_bytes(size)
return BoxReader(io.BytesIO(data), size)

def has_next_box(self):
def has_next_box(self) -> bool:
if self.has_length:
return self.fp.tell() + self.remaining_in_box < self.length
else:
Expand Down
20 changes: 10 additions & 10 deletions src/PIL/PdfParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ class IndirectReferenceTuple(NamedTuple):


class IndirectReference(IndirectReferenceTuple):
def __str__(self):
def __str__(self) -> str:
return f"{self.object_id} {self.generation} R"

def __bytes__(self):
def __bytes__(self) -> bytes:
return self.__str__().encode("us-ascii")

def __eq__(self, other):
Expand All @@ -108,7 +108,7 @@ def __hash__(self):


class IndirectObjectDef(IndirectReference):
def __str__(self):
def __str__(self) -> str:
return f"{self.object_id} {self.generation} obj"


Expand Down Expand Up @@ -150,7 +150,7 @@ def __delitem__(self, key):
def __contains__(self, key):
return key in self.existing_entries or key in self.new_entries

def __len__(self):
def __len__(self) -> int:
return len(
set(self.existing_entries.keys())
| set(self.new_entries.keys())
Expand Down Expand Up @@ -211,7 +211,7 @@ def __init__(self, name):
else:
self.name = name.encode("us-ascii")

def name_as_str(self):
def name_as_str(self) -> str:
return self.name.decode("us-ascii")

def __eq__(self, other):
Expand All @@ -222,7 +222,7 @@ def __eq__(self, other):
def __hash__(self):
return hash(self.name)

def __repr__(self):
def __repr__(self) -> str:
return f"{self.__class__.__name__}({repr(self.name)})"

@classmethod
Expand All @@ -231,7 +231,7 @@ def from_pdf_stream(cls, data):

allowed_chars = set(range(33, 127)) - {ord(c) for c in "#%/()<>[]{}"}

def __bytes__(self):
def __bytes__(self) -> bytes:
result = bytearray(b"/")
for b in self.name:
if b in self.allowed_chars:
Expand All @@ -242,7 +242,7 @@ def __bytes__(self):


class PdfArray(List[Any]):
def __bytes__(self):
def __bytes__(self) -> bytes:
return b"[ " + b" ".join(pdf_repr(x) for x in self) + b" ]"


Expand Down Expand Up @@ -286,7 +286,7 @@ def __getattr__(self, key):
value = time.gmtime(calendar.timegm(value) + offset)
return value

def __bytes__(self):
def __bytes__(self) -> bytes:
out = bytearray(b"<<")
for key, value in self.items():
if value is None:
Expand All @@ -304,7 +304,7 @@ class PdfBinary:
def __init__(self, data):
self.data = data

def __bytes__(self):
def __bytes__(self) -> bytes:
return b"<%s>" % b"".join(b"%02X" % b for b in self.data)


Expand Down
10 changes: 7 additions & 3 deletions src/PIL/SpiderImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import os
import struct
import sys
from typing import TYPE_CHECKING

from . import Image, ImageFile

Expand Down Expand Up @@ -157,11 +158,11 @@ def _open(self) -> None:
self._fp = self.fp # FIXME: hack

@property
def n_frames(self):
def n_frames(self) -> int:
return self._nimages

@property
def is_animated(self):
def is_animated(self) -> bool:
return self._nimages > 1

# 1st image index is zero (although SPIDER imgnumber starts at 1)
Expand Down Expand Up @@ -191,8 +192,11 @@ def convert2byte(self, depth=255):
b = -m * minimum
return self.point(lambda i, m=m, b=b: i * m + b).convert("L")

if TYPE_CHECKING:
from . import ImageTk

# returns a ImageTk.PhotoImage object, after rescaling to 0..255
def tkPhotoImage(self):
def tkPhotoImage(self) -> ImageTk.PhotoImage:
from . import ImageTk

return ImageTk.PhotoImage(self.convert2byte(), palette=256)
Expand Down
14 changes: 7 additions & 7 deletions src/PIL/TiffImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ def limit_rational(self, max_denominator):
f = self._val.limit_denominator(max_denominator)
return f.numerator, f.denominator

def __repr__(self):
def __repr__(self) -> str:
return str(float(self._val))

def __hash__(self):
Expand Down Expand Up @@ -603,7 +603,7 @@ def reset(self):
self._next = None
self._offset = None

def __str__(self):
def __str__(self) -> str:
return str(dict(self))

def named(self):
Expand All @@ -617,7 +617,7 @@ def named(self):
for code, value in self.items()
}

def __len__(self):
def __len__(self) -> int:
return len(set(self._tagdata) | set(self._tags_v2))

def __getitem__(self, tag):
Expand Down Expand Up @@ -1041,7 +1041,7 @@ def from_v2(cls, original):
ifd.next = original.next # an indicator for multipage tiffs
return ifd

def to_v2(self):
def to_v2(self) -> ImageFileDirectory_v2:
"""Returns an
:py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
instance with the same data as is contained in the original
Expand All @@ -1061,7 +1061,7 @@ def to_v2(self):
def __contains__(self, tag):
return tag in self._tags_v1 or tag in self._tagdata

def __len__(self):
def __len__(self) -> int:
return len(set(self._tagdata) | set(self._tags_v1))

def __iter__(self):
Expand Down Expand Up @@ -1154,7 +1154,7 @@ def seek(self, frame: int) -> None:
Image._decompression_bomb_check(self.size)
self.im = Image.core.new(self.mode, self.size)

def _seek(self, frame):
def _seek(self, frame: int) -> None:
self.fp = self._fp

# reset buffered io handle in case fp
Expand Down Expand Up @@ -2003,7 +2003,7 @@ def __exit__(self, exc_type, exc_value, traceback):
self.close()
return False

def tell(self):
def tell(self) -> int:
return self.f.tell() - self.offsetOfNewPage

def seek(self, offset, whence=io.SEEK_SET):
Expand Down
2 changes: 1 addition & 1 deletion src/PIL/WebPImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def _get_next(self):
timestamp -= duration
return data, timestamp, duration

def _seek(self, frame):
def _seek(self, frame: int) -> None:
if self.__physical_frame == frame:
return # Nothing to do
if frame < self.__physical_frame:
Expand Down
Loading