mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-11 04:07:21 +03:00
Add various type annotations
This commit is contained in:
parent
93ca52fbe0
commit
c92f59d758
|
@ -41,7 +41,7 @@ import warnings
|
|||
from collections.abc import Callable, MutableMapping
|
||||
from enum import IntEnum
|
||||
from types import ModuleType
|
||||
from typing import IO, TYPE_CHECKING, Any, Literal, Protocol, Sequence, cast
|
||||
from typing import IO, TYPE_CHECKING, Any, Literal, Protocol, Sequence, cast, overload
|
||||
|
||||
# VERSION was removed in Pillow 6.0.0.
|
||||
# PILLOW_VERSION was removed in Pillow 9.0.0.
|
||||
|
@ -481,6 +481,8 @@ def _getscaleoffset(expr):
|
|||
# --------------------------------------------------------------------
|
||||
# Implementation wrapper
|
||||
|
||||
class _GetDataTransform(Protocol):
|
||||
def getdata(self) -> tuple[Transform, Sequence[int]]: ...
|
||||
|
||||
class Image:
|
||||
"""
|
||||
|
@ -1687,7 +1689,7 @@ class Image:
|
|||
return self.im.entropy(extrema)
|
||||
return self.im.entropy()
|
||||
|
||||
def paste(self, im, box=None, mask=None) -> None:
|
||||
def paste(self, im: Image | str | int | tuple[int, ...], box: tuple[int, int, int, int] | tuple[int, int] | None = None, mask: Image | None = None) -> None:
|
||||
"""
|
||||
Pastes another image into this image. The box argument is either
|
||||
a 2-tuple giving the upper left corner, a 4-tuple defining the
|
||||
|
@ -2122,7 +2124,7 @@ class Image:
|
|||
min(self.size[1], math.ceil(box[3] + support_y)),
|
||||
)
|
||||
|
||||
def resize(self, size, resample=None, box=None, reducing_gap=None) -> Image:
|
||||
def resize(self, size: tuple[int, int], resample: Resampling | None = None, box: tuple[float, float, float, float] | None = None, reducing_gap: float | None = None) -> Image:
|
||||
"""
|
||||
Returns a resized copy of this image.
|
||||
|
||||
|
@ -2228,7 +2230,7 @@ class Image:
|
|||
|
||||
return self._new(self.im.resize(size, resample, box))
|
||||
|
||||
def reduce(self, factor, box=None):
|
||||
def reduce(self, factor: int | tuple[int, int], box: tuple[int, int, int, int] | None = None) -> Image:
|
||||
"""
|
||||
Returns a copy of the image reduced ``factor`` times.
|
||||
If the size of the image is not dividable by ``factor``,
|
||||
|
@ -2263,13 +2265,13 @@ class Image:
|
|||
|
||||
def rotate(
|
||||
self,
|
||||
angle,
|
||||
resample=Resampling.NEAREST,
|
||||
expand=0,
|
||||
center=None,
|
||||
translate=None,
|
||||
fillcolor=None,
|
||||
):
|
||||
angle: float,
|
||||
resample: Resampling = Resampling.NEAREST,
|
||||
expand: bool = False,
|
||||
center: tuple[int, int] | None = None,
|
||||
translate: tuple[int, int] | None = None,
|
||||
fillcolor: float | tuple[float, ...] | str | None = None,
|
||||
) -> Image:
|
||||
"""
|
||||
Returns a rotated copy of this image. This method returns a
|
||||
copy of this image, rotated the given number of degrees counter
|
||||
|
@ -2576,7 +2578,7 @@ class Image:
|
|||
"""
|
||||
return 0
|
||||
|
||||
def thumbnail(self, size, resample=Resampling.BICUBIC, reducing_gap=2.0):
|
||||
def thumbnail(self, size: tuple[int, int], resample: Resampling = Resampling.BICUBIC, reducing_gap: float = 2.0) -> None:
|
||||
"""
|
||||
Make this image into a thumbnail. This method modifies the
|
||||
image to contain a thumbnail version of itself, no larger than
|
||||
|
@ -2664,14 +2666,34 @@ class Image:
|
|||
|
||||
# FIXME: the different transform methods need further explanation
|
||||
# instead of bloating the method docs, add a separate chapter.
|
||||
@overload
|
||||
def transform(
|
||||
self,
|
||||
size,
|
||||
method,
|
||||
data=None,
|
||||
resample=Resampling.NEAREST,
|
||||
fill=1,
|
||||
fillcolor=None,
|
||||
size: tuple[int, int],
|
||||
method: Transform | ImageTransformHandler,
|
||||
data: Sequence[int],
|
||||
resample: Resampling = Resampling.NEAREST,
|
||||
fill: int = 1,
|
||||
fillcolor: float | tuple[float, ...] | str | None = None,
|
||||
) -> Image: ...
|
||||
@overload
|
||||
def transform(
|
||||
self,
|
||||
size: tuple[int, int],
|
||||
method: _GetDataTransform,
|
||||
data: None = None,
|
||||
resample: Resampling = Resampling.NEAREST,
|
||||
fill: int = 1,
|
||||
fillcolor: float | tuple[float, ...] | str | None = None,
|
||||
) -> Image: ...
|
||||
def transform(
|
||||
self,
|
||||
size: tuple[int, int],
|
||||
method: Transform | ImageTransformHandler | _GetDataTransform,
|
||||
data: Sequence[int] | None = None,
|
||||
resample: Resampling = Resampling.NEAREST,
|
||||
fill: int = 1,
|
||||
fillcolor: float | tuple[float, ...] | str | None = None,
|
||||
) -> Image:
|
||||
"""
|
||||
Transforms this image. This method creates a new image with the
|
||||
|
|
|
@ -34,10 +34,11 @@ from __future__ import annotations
|
|||
import math
|
||||
import numbers
|
||||
import struct
|
||||
from typing import Sequence, cast
|
||||
from typing import AnyStr, Sequence, cast
|
||||
|
||||
from . import Image, ImageColor
|
||||
from ._typing import Coords
|
||||
from .ImageFont import FreeTypeFont, ImageFont
|
||||
|
||||
"""
|
||||
A simple 2D drawing interface for PIL images.
|
||||
|
@ -92,7 +93,7 @@ class ImageDraw:
|
|||
self.fontmode = "L" # aliasing is okay for other modes
|
||||
self.fill = False
|
||||
|
||||
def getfont(self):
|
||||
def getfont(self) -> FreeTypeFont | ImageFont:
|
||||
"""
|
||||
Get the current default font.
|
||||
|
||||
|
@ -450,12 +451,12 @@ class ImageDraw:
|
|||
right[3] -= r + 1
|
||||
self.draw.draw_rectangle(right, ink, 1)
|
||||
|
||||
def _multiline_check(self, text) -> bool:
|
||||
def _multiline_check(self, text: str | bytes) -> bool:
|
||||
split_character = "\n" if isinstance(text, str) else b"\n"
|
||||
|
||||
return split_character in text
|
||||
|
||||
def _multiline_split(self, text) -> list[str | bytes]:
|
||||
def _multiline_split(self, text: AnyStr) -> list[AnyStr]:
|
||||
split_character = "\n" if isinstance(text, str) else b"\n"
|
||||
|
||||
return text.split(split_character)
|
||||
|
@ -469,7 +470,7 @@ class ImageDraw:
|
|||
|
||||
def text(
|
||||
self,
|
||||
xy,
|
||||
xy: tuple[int, int],
|
||||
text,
|
||||
fill=None,
|
||||
font=None,
|
||||
|
@ -591,7 +592,7 @@ class ImageDraw:
|
|||
|
||||
def multiline_text(
|
||||
self,
|
||||
xy,
|
||||
xy: tuple[int, int],
|
||||
text,
|
||||
fill=None,
|
||||
font=None,
|
||||
|
@ -678,15 +679,15 @@ class ImageDraw:
|
|||
|
||||
def textlength(
|
||||
self,
|
||||
text,
|
||||
font=None,
|
||||
text: str,
|
||||
font: FreeTypeFont | ImageFont | None = None,
|
||||
direction=None,
|
||||
features=None,
|
||||
language=None,
|
||||
embedded_color=False,
|
||||
*,
|
||||
font_size=None,
|
||||
):
|
||||
) -> float:
|
||||
"""Get the length of a given string, in pixels with 1/64 precision."""
|
||||
if self._multiline_check(text):
|
||||
msg = "can't measure length of multiline text"
|
||||
|
|
|
@ -33,12 +33,15 @@ import sys
|
|||
import warnings
|
||||
from enum import IntEnum
|
||||
from io import BytesIO
|
||||
from typing import BinaryIO
|
||||
from typing import TYPE_CHECKING, BinaryIO
|
||||
|
||||
from . import Image
|
||||
from ._typing import StrOrBytesPath
|
||||
from ._util import is_directory, is_path
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from _imagingft import Font
|
||||
|
||||
|
||||
class Layout(IntEnum):
|
||||
BASIC = 0
|
||||
|
@ -56,7 +59,7 @@ except ImportError as ex:
|
|||
core = DeferredError.new(ex)
|
||||
|
||||
|
||||
def _string_length_check(text):
|
||||
def _string_length_check(text: str | bytes) -> None:
|
||||
if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH:
|
||||
msg = "too many characters in string"
|
||||
raise ValueError(msg)
|
||||
|
@ -81,7 +84,9 @@ def _string_length_check(text):
|
|||
class ImageFont:
|
||||
"""PIL font wrapper"""
|
||||
|
||||
def _load_pilfont(self, filename):
|
||||
font: Font
|
||||
|
||||
def _load_pilfont(self, filename: str) -> None:
|
||||
with open(filename, "rb") as fp:
|
||||
image = None
|
||||
for ext in (".png", ".gif", ".pbm"):
|
||||
|
@ -153,7 +158,7 @@ class ImageFont:
|
|||
Image._decompression_bomb_check(self.font.getsize(text))
|
||||
return self.font.getmask(text, mode)
|
||||
|
||||
def getbbox(self, text, *args, **kwargs):
|
||||
def getbbox(self, text: str, *args: object, **kwargs: object) -> tuple[int, int, int, int]:
|
||||
"""
|
||||
Returns bounding box (in pixels) of given text.
|
||||
|
||||
|
@ -171,7 +176,7 @@ class ImageFont:
|
|||
width, height = self.font.getsize(text)
|
||||
return 0, 0, width, height
|
||||
|
||||
def getlength(self, text, *args, **kwargs):
|
||||
def getlength(self, text: str, *args: object, **kwargs: object) -> int:
|
||||
"""
|
||||
Returns length (in pixels) of given text.
|
||||
This is the amount by which following text should be offset.
|
||||
|
@ -254,7 +259,7 @@ class FreeTypeFont:
|
|||
path, size, index, encoding, layout_engine = state
|
||||
self.__init__(path, size, index, encoding, layout_engine)
|
||||
|
||||
def getname(self):
|
||||
def getname(self) -> tuple[str, str]:
|
||||
"""
|
||||
:return: A tuple of the font family (e.g. Helvetica) and the font style
|
||||
(e.g. Bold)
|
||||
|
@ -269,7 +274,7 @@ class FreeTypeFont:
|
|||
"""
|
||||
return self.font.ascent, self.font.descent
|
||||
|
||||
def getlength(self, text, mode="", direction=None, features=None, language=None):
|
||||
def getlength(self, text: str, mode="", direction=None, features=None, language=None) -> float:
|
||||
"""
|
||||
Returns length (in pixels with 1/64 precision) of given text when rendered
|
||||
in font with provided direction, features, and language.
|
||||
|
@ -343,14 +348,14 @@ class FreeTypeFont:
|
|||
|
||||
def getbbox(
|
||||
self,
|
||||
text,
|
||||
text: str,
|
||||
mode="",
|
||||
direction=None,
|
||||
features=None,
|
||||
language=None,
|
||||
stroke_width=0,
|
||||
anchor=None,
|
||||
):
|
||||
) -> tuple[int, int, int, int]:
|
||||
"""
|
||||
Returns bounding box (in pixels) of given text relative to given anchor
|
||||
when rendered in font with provided direction, features, and language.
|
||||
|
@ -725,7 +730,7 @@ class TransposedFont:
|
|||
return self.font.getlength(text, *args, **kwargs)
|
||||
|
||||
|
||||
def load(filename):
|
||||
def load(filename: str) -> ImageFont:
|
||||
"""
|
||||
Load a font file. This function loads a font object from the given
|
||||
bitmap font file, and returns the corresponding font object.
|
||||
|
@ -739,7 +744,7 @@ def load(filename):
|
|||
return f
|
||||
|
||||
|
||||
def truetype(font=None, size=10, index=0, encoding="", layout_engine=None):
|
||||
def truetype(font: StrOrBytesPath | BinaryIO | None = None, size: float = 10, index: int = 0, encoding: str = "", layout_engine: Layout | None = None) -> FreeTypeFont:
|
||||
"""
|
||||
Load a TrueType or OpenType font from a file or file-like object,
|
||||
and create a font object.
|
||||
|
@ -800,7 +805,7 @@ def truetype(font=None, size=10, index=0, encoding="", layout_engine=None):
|
|||
:exception ValueError: If the font size is not greater than zero.
|
||||
"""
|
||||
|
||||
def freetype(font):
|
||||
def freetype(font: StrOrBytesPath | BinaryIO | None) -> FreeTypeFont:
|
||||
return FreeTypeFont(font, size, index, encoding, layout_engine)
|
||||
|
||||
try:
|
||||
|
@ -850,7 +855,7 @@ def truetype(font=None, size=10, index=0, encoding="", layout_engine=None):
|
|||
raise
|
||||
|
||||
|
||||
def load_path(filename):
|
||||
def load_path(filename: str | bytes) -> ImageFont:
|
||||
"""
|
||||
Load font file. Same as :py:func:`~PIL.ImageFont.load`, but searches for a
|
||||
bitmap font along the Python path.
|
||||
|
|
|
@ -1,3 +1,38 @@
|
|||
from typing import Any
|
||||
from typing import Any, TypedDict
|
||||
|
||||
class _Axis(TypedDict):
|
||||
minimum: int | None
|
||||
default: int | None
|
||||
maximum: int | None
|
||||
name: str | None
|
||||
|
||||
|
||||
class Font:
|
||||
@property
|
||||
def family(self) -> str | None: ...
|
||||
@property
|
||||
def style(self) -> str | None: ...
|
||||
@property
|
||||
def ascent(self) -> int: ...
|
||||
@property
|
||||
def descent(self) -> int: ...
|
||||
@property
|
||||
def height(self) -> int: ...
|
||||
@property
|
||||
def x_ppem(self) -> int: ...
|
||||
@property
|
||||
def y_ppem(self) -> int: ...
|
||||
@property
|
||||
def glyphs(self) -> int: ...
|
||||
|
||||
def render(self, string: str, fill, mode = ..., dir = ..., features = ..., lang = ..., stroke_width = ..., anchor = ..., foreground_ink_long = ..., x_start = ..., y_start = ..., /) -> tuple[Any, tuple[int, int]]: ...
|
||||
def getsize(self, string: str, mode = ..., dir = ..., features = ..., lang = ..., anchor = ..., /) -> tuple[tuple[int, int], tuple[int, int]]: ...
|
||||
def getlength(self, string: str, mode = ..., dir = ..., features = ..., lang = ..., /) -> int: ...
|
||||
def getvarnames(self) -> list[str]: ...
|
||||
def getvaraxes(self) -> list[_Axis]: ...
|
||||
def setvarname(self, instance_index: int, /) -> None: ...
|
||||
def setvaraxes(self, axes: list[float], /) -> None: ...
|
||||
|
||||
def getfont(filename: str | bytes | bytearray, size, index = ..., encoding = ..., font_bytes = ..., layout_engine = ...) -> Font: ...
|
||||
|
||||
def __getattr__(name: str) -> Any: ...
|
||||
|
|
Loading…
Reference in New Issue
Block a user