Skip to content

Commit 1eb960f

Browse files
committed
Added type hints
1 parent 780d85b commit 1eb960f

16 files changed

+78
-85
lines changed

src/PIL/BlpImagePlugin.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,17 +61,19 @@ def unpack_565(i: int) -> tuple[int, int, int]:
6161
return ((i >> 11) & 0x1F) << 3, ((i >> 5) & 0x3F) << 2, (i & 0x1F) << 3
6262

6363

64-
def decode_dxt1(data, alpha=False):
64+
def decode_dxt1(
65+
data: bytes, alpha: bool = False
66+
) -> tuple[bytearray, bytearray, bytearray, bytearray]:
6567
"""
6668
input: one "row" of data (i.e. will produce 4*width pixels)
6769
"""
6870

6971
blocks = len(data) // 8 # number of blocks in row
7072
ret = (bytearray(), bytearray(), bytearray(), bytearray())
7173

72-
for block in range(blocks):
74+
for block_index in range(blocks):
7375
# Decode next 8-byte block.
74-
idx = block * 8
76+
idx = block_index * 8
7577
color0, color1, bits = struct.unpack_from("<HHI", data, idx)
7678

7779
r0, g0, b0 = unpack_565(color0)
@@ -116,16 +118,16 @@ def decode_dxt1(data, alpha=False):
116118
return ret
117119

118120

119-
def decode_dxt3(data):
121+
def decode_dxt3(data: bytes) -> tuple[bytearray, bytearray, bytearray, bytearray]:
120122
"""
121123
input: one "row" of data (i.e. will produce 4*width pixels)
122124
"""
123125

124126
blocks = len(data) // 16 # number of blocks in row
125127
ret = (bytearray(), bytearray(), bytearray(), bytearray())
126128

127-
for block in range(blocks):
128-
idx = block * 16
129+
for block_index in range(blocks):
130+
idx = block_index * 16
129131
block = data[idx : idx + 16]
130132
# Decode next 16-byte block.
131133
bits = struct.unpack_from("<8B", block)
@@ -169,16 +171,16 @@ def decode_dxt3(data):
169171
return ret
170172

171173

172-
def decode_dxt5(data):
174+
def decode_dxt5(data: bytes) -> tuple[bytearray, bytearray, bytearray, bytearray]:
173175
"""
174176
input: one "row" of data (i.e. will produce 4 * width pixels)
175177
"""
176178

177179
blocks = len(data) // 16 # number of blocks in row
178180
ret = (bytearray(), bytearray(), bytearray(), bytearray())
179181

180-
for block in range(blocks):
181-
idx = block * 16
182+
for block_index in range(blocks):
183+
idx = block_index * 16
182184
block = data[idx : idx + 16]
183185
# Decode next 16-byte block.
184186
a0, a1 = struct.unpack_from("<BB", block)

src/PIL/BmpImagePlugin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,8 @@ def _open(self) -> None:
301301
class BmpRleDecoder(ImageFile.PyDecoder):
302302
_pulls_fd = True
303303

304-
def decode(self, buffer):
304+
def decode(self, buffer: bytes) -> tuple[int, int]:
305+
assert self.fd is not None
305306
rle4 = self.args[1]
306307
data = bytearray()
307308
x = 0

src/PIL/DdsImagePlugin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,8 @@ def load_seek(self, pos: int) -> None:
480480
class DdsRgbDecoder(ImageFile.PyDecoder):
481481
_pulls_fd = True
482482

483-
def decode(self, buffer):
483+
def decode(self, buffer: bytes) -> tuple[int, int]:
484+
assert self.fd is not None
484485
bitcount, masks = self.args
485486

486487
# Some masks will be padded with zeros, e.g. R 0b11 G 0b1100

src/PIL/EpsImagePlugin.py

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import subprocess
2828
import sys
2929
import tempfile
30+
from typing import IO
3031

3132
from . import Image, ImageFile
3233
from ._binary import i32le as i32
@@ -236,35 +237,33 @@ def check_required_header_comments() -> None:
236237
msg = 'EPS header missing "%%BoundingBox" comment'
237238
raise SyntaxError(msg)
238239

239-
def _read_comment(s):
240+
def _read_comment(s: str) -> bool:
240241
nonlocal reading_trailer_comments
241242
try:
242243
m = split.match(s)
243244
except re.error as e:
244245
msg = "not an EPS file"
245246
raise SyntaxError(msg) from e
246247

247-
if m:
248-
k, v = m.group(1, 2)
249-
self.info[k] = v
250-
if k == "BoundingBox":
251-
if v == "(atend)":
252-
reading_trailer_comments = True
253-
elif not self._size or (
254-
trailer_reached and reading_trailer_comments
255-
):
256-
try:
257-
# Note: The DSC spec says that BoundingBox
258-
# fields should be integers, but some drivers
259-
# put floating point values there anyway.
260-
box = [int(float(i)) for i in v.split()]
261-
self._size = box[2] - box[0], box[3] - box[1]
262-
self.tile = [
263-
("eps", (0, 0) + self.size, offset, (length, box))
264-
]
265-
except Exception:
266-
pass
267-
return True
248+
if not m:
249+
return False
250+
251+
k, v = m.group(1, 2)
252+
self.info[k] = v
253+
if k == "BoundingBox":
254+
if v == "(atend)":
255+
reading_trailer_comments = True
256+
elif not self._size or (trailer_reached and reading_trailer_comments):
257+
try:
258+
# Note: The DSC spec says that BoundingBox
259+
# fields should be integers, but some drivers
260+
# put floating point values there anyway.
261+
box = [int(float(i)) for i in v.split()]
262+
self._size = box[2] - box[0], box[3] - box[1]
263+
self.tile = [("eps", (0, 0) + self.size, offset, (length, box))]
264+
except Exception:
265+
pass
266+
return True
268267

269268
while True:
270269
byte = self.fp.read(1)
@@ -413,7 +412,7 @@ def load_seek(self, pos: int) -> None:
413412
# --------------------------------------------------------------------
414413

415414

416-
def _save(im, fp, filename, eps=1):
415+
def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes, eps: int = 1) -> None:
417416
"""EPS Writer for the Python Imaging Library."""
418417

419418
# make sure image data is available

src/PIL/FitsImagePlugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def _parse_headers(
122122
class FitsGzipDecoder(ImageFile.PyDecoder):
123123
_pulls_fd = True
124124

125-
def decode(self, buffer):
125+
def decode(self, buffer: bytes) -> tuple[int, int]:
126126
assert self.fd is not None
127127
value = gzip.decompress(self.fd.read())
128128

src/PIL/FpxImagePlugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ def close(self) -> None:
241241
self.ole.close()
242242
super().close()
243243

244-
def __exit__(self, *args):
244+
def __exit__(self, *args: object) -> None:
245245
self.ole.close()
246246
super().__exit__()
247247

src/PIL/ImageFile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ def feed(self, data):
487487
def __enter__(self):
488488
return self
489489

490-
def __exit__(self, *args):
490+
def __exit__(self, *args: object) -> None:
491491
self.close()
492492

493493
def close(self):

src/PIL/Jpeg2KImagePlugin.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import io
1919
import os
2020
import struct
21-
from typing import IO
21+
from typing import IO, Tuple, cast
2222

2323
from . import Image, ImageFile, ImagePalette, _binary
2424

@@ -59,7 +59,7 @@ def _read_bytes(self, num_bytes: int) -> bytes:
5959
self.remaining_in_box -= num_bytes
6060
return data
6161

62-
def read_fields(self, field_format):
62+
def read_fields(self, field_format: str) -> tuple[int | bytes, ...]:
6363
size = struct.calcsize(field_format)
6464
data = self._read_bytes(size)
6565
return struct.unpack(field_format, data)
@@ -82,9 +82,9 @@ def next_box_type(self) -> bytes:
8282
self.remaining_in_box = -1
8383

8484
# Read the length and type of the next box
85-
lbox, tbox = self.read_fields(">I4s")
85+
lbox, tbox = cast(Tuple[int, bytes], self.read_fields(">I4s"))
8686
if lbox == 1:
87-
lbox = self.read_fields(">Q")[0]
87+
lbox = cast(int, self.read_fields(">Q")[0])
8888
hlen = 16
8989
else:
9090
hlen = 8
@@ -127,12 +127,13 @@ def _parse_codestream(fp):
127127
return size, mode
128128

129129

130-
def _res_to_dpi(num, denom, exp):
130+
def _res_to_dpi(num: int, denom: int, exp: int) -> float | None:
131131
"""Convert JPEG2000's (numerator, denominator, exponent-base-10) resolution,
132132
calculated as (num / denom) * 10^exp and stored in dots per meter,
133133
to floating-point dots per inch."""
134-
if denom != 0:
135-
return (254 * num * (10**exp)) / (10000 * denom)
134+
if denom == 0:
135+
return None
136+
return (254 * num * (10**exp)) / (10000 * denom)
136137

137138

138139
def _parse_jp2_header(fp):

src/PIL/MicImagePlugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def close(self) -> None:
9393
self.ole.close()
9494
super().close()
9595

96-
def __exit__(self, *args):
96+
def __exit__(self, *args: object) -> None:
9797
self.__fp.close()
9898
self.ole.close()
9999
super().__exit__()

src/PIL/MpoImagePlugin.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,14 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
3737
JpegImagePlugin._save(im, fp, filename)
3838

3939

40-
def _save_all(im, fp, filename):
40+
def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
4141
append_images = im.encoderinfo.get("append_images", [])
42-
if not append_images:
43-
try:
44-
animated = im.is_animated
45-
except AttributeError:
46-
animated = False
47-
if not animated:
48-
_save(im, fp, filename)
49-
return
42+
if not append_images and not getattr(im, "is_animated", False):
43+
_save(im, fp, filename)
44+
return
5045

5146
mpf_offset = 28
52-
offsets = []
47+
offsets: list[int] = []
5348
for imSequence in itertools.chain([im], append_images):
5449
for im_frame in ImageSequence.Iterator(imSequence):
5550
if not offsets:

0 commit comments

Comments
 (0)