Skip to content

Commit d566c04

Browse files
committed
Updated type hints
1 parent c0ee645 commit d566c04

File tree

6 files changed

+75
-58
lines changed

6 files changed

+75
-58
lines changed

src/PIL/Image.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ def _getscaleoffset(expr):
506506
class SupportsGetData(Protocol):
507507
def getdata(
508508
self,
509-
) -> tuple[Transform, Sequence[Any]]: ...
509+
) -> tuple[Transform, Sequence[int]]: ...
510510

511511

512512
class Image:
@@ -1295,7 +1295,7 @@ def _crop(self, im, box):
12951295
return im.crop((x0, y0, x1, y1))
12961296

12971297
def draft(
1298-
self, mode: str, size: tuple[int, int]
1298+
self, mode: str | None, size: tuple[int, int]
12991299
) -> tuple[str, tuple[int, int, float, float]] | None:
13001300
"""
13011301
Configures the image file loader so it returns a version of the
@@ -1719,7 +1719,7 @@ def entropy(self, mask=None, extrema=None):
17191719

17201720
def paste(
17211721
self,
1722-
im: Image | str | int | tuple[int, ...],
1722+
im: Image | str | float | tuple[int, ...],
17231723
box: tuple[int, int, int, int] | tuple[int, int] | None = None,
17241724
mask: Image | None = None,
17251725
) -> None:
@@ -1750,7 +1750,7 @@ def paste(
17501750
See :py:meth:`~PIL.Image.Image.alpha_composite` if you want to
17511751
combine images with respect to their alpha channels.
17521752
1753-
:param im: Source image or pixel value (integer or tuple).
1753+
:param im: Source image or pixel value (integer, float or tuple).
17541754
:param box: An optional 4-tuple giving the region to paste into.
17551755
If a 2-tuple is used instead, it's treated as the upper left
17561756
corner. If omitted or None, the source is pasted into the
@@ -2228,13 +2228,9 @@ def resize(
22282228
msg = "reducing_gap must be 1.0 or greater"
22292229
raise ValueError(msg)
22302230

2231-
size = cast("tuple[int, int]", tuple(size))
2232-
22332231
self.load()
22342232
if box is None:
22352233
box = (0, 0) + self.size
2236-
else:
2237-
box = cast("tuple[float, float, float, float]", tuple(box))
22382234

22392235
if self.size == size and box == (0, 0) + self.size:
22402236
return self.copy()
@@ -2291,8 +2287,6 @@ def reduce(
22912287

22922288
if box is None:
22932289
box = (0, 0) + self.size
2294-
else:
2295-
box = cast("tuple[int, int, int, int]", tuple(box))
22962290

22972291
if factor == (1, 1) and box == (0, 0) + self.size:
22982292
return self.copy()
@@ -2692,7 +2686,9 @@ def round_aspect(number, key):
26922686
return
26932687
size = preserved_size
26942688

2695-
res = self.draft(None, (size[0] * reducing_gap, size[1] * reducing_gap)) # type: ignore[arg-type]
2689+
res = self.draft(
2690+
None, (int(size[0] * reducing_gap), int(size[1] * reducing_gap))
2691+
)
26962692
if res is not None:
26972693
box = res[1]
26982694
if box is None:
@@ -2799,7 +2795,7 @@ def getdata(self):
27992795
im.info = self.info.copy()
28002796
if method == Transform.MESH:
28012797
# list of quads
2802-
for box, quad in cast("Sequence[tuple[float, float]]", data):
2798+
for box, quad in data:
28032799
im.__transformer(
28042800
box, self, Transform.QUAD, quad, resample, fillcolor is None
28052801
)
@@ -2957,7 +2953,7 @@ def transform(
29572953
self,
29582954
size: tuple[int, int],
29592955
image: Image,
2960-
**options: dict[str, str | int | tuple[int, ...] | list[int]] | int,
2956+
**options: str | int | tuple[int, ...] | list[int],
29612957
) -> Image:
29622958
pass
29632959

src/PIL/ImageDraw.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -456,14 +456,12 @@ def draw_corners(pieslice) -> None:
456456
self.draw.draw_rectangle(right, ink, 1)
457457

458458
def _multiline_check(self, text: AnyStr) -> bool:
459-
split_character = cast(AnyStr, "\n" if isinstance(text, str) else b"\n")
459+
split_character = "\n" if isinstance(text, str) else b"\n"
460460

461461
return split_character in text
462462

463463
def _multiline_split(self, text: AnyStr) -> list[AnyStr]:
464-
split_character = cast(AnyStr, "\n" if isinstance(text, str) else b"\n")
465-
466-
return text.split(split_character)
464+
return text.split("\n" if isinstance(text, str) else b"\n")
467465

468466
def _multiline_spacing(self, font, spacing, stroke_width):
469467
return (
@@ -477,7 +475,12 @@ def text(
477475
xy: tuple[float, float],
478476
text: str,
479477
fill=None,
480-
font: ImageFont.FreeTypeFont | ImageFont.ImageFont | None = None,
478+
font: (
479+
ImageFont.ImageFont
480+
| ImageFont.FreeTypeFont
481+
| ImageFont.TransposedFont
482+
| None
483+
) = None,
481484
anchor=None,
482485
spacing=4,
483486
align="left",
@@ -597,9 +600,14 @@ def draw_text(ink, stroke_width=0, stroke_offset=None) -> None:
597600
def multiline_text(
598601
self,
599602
xy: tuple[float, float],
600-
text,
603+
text: str,
601604
fill=None,
602-
font=None,
605+
font: (
606+
ImageFont.ImageFont
607+
| ImageFont.FreeTypeFont
608+
| ImageFont.TransposedFont
609+
| None
610+
) = None,
603611
anchor=None,
604612
spacing=4,
605613
align="left",
@@ -684,7 +692,12 @@ def multiline_text(
684692
def textlength(
685693
self,
686694
text: str,
687-
font: ImageFont.FreeTypeFont | ImageFont.ImageFont | None = None,
695+
font: (
696+
ImageFont.ImageFont
697+
| ImageFont.FreeTypeFont
698+
| ImageFont.TransposedFont
699+
| None
700+
) = None,
688701
direction=None,
689702
features=None,
690703
language=None,

src/PIL/ImageFont.py

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@
3333
import warnings
3434
from enum import IntEnum
3535
from io import BytesIO
36-
from typing import TYPE_CHECKING, BinaryIO
36+
from typing import IO, TYPE_CHECKING, Any, BinaryIO
3737

3838
from . import Image
3939
from ._typing import StrOrBytesPath
40-
from ._util import is_directory, is_path
40+
from ._util import is_path
4141

4242
if TYPE_CHECKING:
4343
from . import ImageFile
@@ -61,7 +61,7 @@ class Layout(IntEnum):
6161
core = DeferredError.new(ex)
6262

6363

64-
def _string_length_check(text: str) -> None:
64+
def _string_length_check(text: str | bytes | bytearray) -> None:
6565
if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH:
6666
msg = "too many characters in string"
6767
raise ValueError(msg)
@@ -113,7 +113,7 @@ def _load_pilfont(self, filename: str) -> None:
113113
self._load_pilfont_data(fp, image)
114114
image.close()
115115

116-
def _load_pilfont_data(self, file, image):
116+
def _load_pilfont_data(self, file: IO[bytes], image: Image.Image) -> None:
117117
# read PILfont header
118118
if file.readline() != b"PILfont\n":
119119
msg = "Not a PILfont file"
@@ -161,7 +161,7 @@ def getmask(self, text, mode="", *args, **kwargs):
161161
return self.font.getmask(text, mode)
162162

163163
def getbbox(
164-
self, text: str, *args: object, **kwargs: object
164+
self, text: str | bytes | bytearray, *args: Any, **kwargs: Any
165165
) -> tuple[int, int, int, int]:
166166
"""
167167
Returns bounding box (in pixels) of given text.
@@ -180,7 +180,9 @@ def getbbox(
180180
width, height = self.font.getsize(text)
181181
return 0, 0, width, height
182182

183-
def getlength(self, text: str, *args: object, **kwargs: object) -> int:
183+
def getlength(
184+
self, text: str | bytes | bytearray, *args: Any, **kwargs: Any
185+
) -> int:
184186
"""
185187
Returns length (in pixels) of given text.
186188
This is the amount by which following text should be offset.
@@ -357,13 +359,13 @@ def getlength(
357359
def getbbox(
358360
self,
359361
text: str,
360-
mode="",
361-
direction=None,
362-
features=None,
363-
language=None,
364-
stroke_width=0,
365-
anchor=None,
366-
) -> tuple[int, int, int, int]:
362+
mode: str = "",
363+
direction: str | None = None,
364+
features: str | None = None,
365+
language: str | None = None,
366+
stroke_width: float = 0,
367+
anchor: str | None = None,
368+
) -> tuple[float, float, float, float]:
367369
"""
368370
Returns bounding box (in pixels) of given text relative to given anchor
369371
when rendered in font with provided direction, features, and language.
@@ -513,7 +515,7 @@ def getmask(
513515

514516
def getmask2(
515517
self,
516-
text,
518+
text: str,
517519
mode="",
518520
direction=None,
519521
features=None,
@@ -641,7 +643,7 @@ def font_variant(
641643
layout_engine=layout_engine or self.layout_engine,
642644
)
643645

644-
def get_variation_names(self):
646+
def get_variation_names(self) -> list[bytes]:
645647
"""
646648
:returns: A list of the named styles in a variation font.
647649
:exception OSError: If the font is not a variation font.
@@ -683,10 +685,11 @@ def get_variation_axes(self):
683685
msg = "FreeType 2.9.1 or greater is required"
684686
raise NotImplementedError(msg) from e
685687
for axis in axes:
686-
axis["name"] = axis["name"].replace(b"\x00", b"")
688+
if axis["name"]:
689+
axis["name"] = axis["name"].replace(b"\x00", b"")
687690
return axes
688691

689-
def set_variation_by_axes(self, axes):
692+
def set_variation_by_axes(self, axes: list[float]) -> None:
690693
"""
691694
:param axes: A list of values for each axis.
692695
:exception OSError: If the font is not a variation font.
@@ -731,7 +734,7 @@ def getbbox(self, text, *args, **kwargs):
731734
return 0, 0, height, width
732735
return 0, 0, width, height
733736

734-
def getlength(self, text, *args, **kwargs):
737+
def getlength(self, text: str, *args, **kwargs) -> float:
735738
if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270):
736739
msg = "text length is undefined for text rotated by 90 or 270 degrees"
737740
raise ValueError(msg)
@@ -878,15 +881,13 @@ def load_path(filename: str | bytes) -> ImageFont:
878881
:return: A font object.
879882
:exception OSError: If the file could not be read.
880883
"""
884+
if not isinstance(filename, str):
885+
filename = filename.decode("utf-8")
881886
for directory in sys.path:
882-
if is_directory(directory):
883-
assert isinstance(directory, str)
884-
if not isinstance(filename, str):
885-
filename = filename.decode("utf-8")
886-
try:
887-
return load(os.path.join(directory, filename))
888-
except OSError:
889-
pass
887+
try:
888+
return load(os.path.join(directory, filename))
889+
except OSError:
890+
pass
890891
msg = "cannot find font file"
891892
raise OSError(msg)
892893

src/PIL/JpegImagePlugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ def load_read(self, read_bytes: int) -> bytes:
425425
return s
426426

427427
def draft(
428-
self, mode: str, size: tuple[int, int]
428+
self, mode: str | None, size: tuple[int, int]
429429
) -> tuple[str, tuple[int, int, float, float]] | None:
430430
if len(self.tile) != 1:
431431
return None

src/PIL/_imaging.pyi

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from typing import Any
22

3-
from typing_extensions import Buffer
4-
53
class ImagingCore:
64
def __getattr__(self, name: str) -> Any: ...
75

@@ -14,5 +12,5 @@ class ImagingDraw:
1412
class PixelAccess:
1513
def __getattr__(self, name: str) -> Any: ...
1614

17-
def font(image, glyphdata: Buffer) -> ImagingFont: ...
15+
def font(image, glyphdata: bytes) -> ImagingFont: ...
1816
def __getattr__(name: str) -> Any: ...

src/PIL/_imagingft.pyi

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from typing import Any, TypedDict
22

3+
from . import _imaging
4+
35
class _Axis(TypedDict):
46
minimum: int | None
57
default: int | None
@@ -37,21 +39,28 @@ class Font:
3739
x_start=...,
3840
y_start=...,
3941
/,
40-
) -> tuple[Any, tuple[int, int]]: ...
42+
) -> tuple[_imaging.ImagingCore, tuple[int, int]]: ...
4143
def getsize(
42-
self, string: str, mode=..., dir=..., features=..., lang=..., anchor=..., /
44+
self,
45+
string: str | bytes | bytearray,
46+
mode=...,
47+
dir=...,
48+
features=...,
49+
lang=...,
50+
anchor=...,
51+
/,
4352
) -> tuple[tuple[int, int], tuple[int, int]]: ...
4453
def getlength(
4554
self, string: str, mode=..., dir=..., features=..., lang=..., /
46-
) -> int: ...
47-
def getvarnames(self) -> list[str]: ...
48-
def getvaraxes(self) -> list[_Axis]: ...
55+
) -> float: ...
56+
def getvarnames(self) -> list[bytes]: ...
57+
def getvaraxes(self) -> list[_Axis] | None: ...
4958
def setvarname(self, instance_index: int, /) -> None: ...
5059
def setvaraxes(self, axes: list[float], /) -> None: ...
5160

5261
def getfont(
53-
filename: str | bytes | bytearray,
54-
size,
62+
filename: str | bytes,
63+
size: float,
5564
index=...,
5665
encoding=...,
5766
font_bytes=...,

0 commit comments

Comments
 (0)