mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 01:16:16 +03:00
Merge remote-tracking branch 'radarhere/type-annotations' into type-annotations
This commit is contained in:
commit
f3ec2770e6
|
@ -506,7 +506,7 @@ def _getscaleoffset(expr):
|
||||||
class SupportsGetData(Protocol):
|
class SupportsGetData(Protocol):
|
||||||
def getdata(
|
def getdata(
|
||||||
self,
|
self,
|
||||||
) -> tuple[Transform, Sequence[Any]]: ...
|
) -> tuple[Transform, Sequence[int]]: ...
|
||||||
|
|
||||||
|
|
||||||
class Image:
|
class Image:
|
||||||
|
@ -1295,7 +1295,7 @@ class Image:
|
||||||
return im.crop((x0, y0, x1, y1))
|
return im.crop((x0, y0, x1, y1))
|
||||||
|
|
||||||
def draft(
|
def draft(
|
||||||
self, mode: str, size: tuple[int, int]
|
self, mode: str | None, size: tuple[int, int]
|
||||||
) -> tuple[str, tuple[int, int, float, float]] | None:
|
) -> tuple[str, tuple[int, int, float, float]] | None:
|
||||||
"""
|
"""
|
||||||
Configures the image file loader so it returns a version of the
|
Configures the image file loader so it returns a version of the
|
||||||
|
@ -1719,7 +1719,7 @@ class Image:
|
||||||
|
|
||||||
def paste(
|
def paste(
|
||||||
self,
|
self,
|
||||||
im: Image | str | int | tuple[int, ...],
|
im: Image | str | float | tuple[int, ...],
|
||||||
box: tuple[int, int, int, int] | tuple[int, int] | None = None,
|
box: tuple[int, int, int, int] | tuple[int, int] | None = None,
|
||||||
mask: Image | None = None,
|
mask: Image | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -1750,7 +1750,7 @@ class Image:
|
||||||
See :py:meth:`~PIL.Image.Image.alpha_composite` if you want to
|
See :py:meth:`~PIL.Image.Image.alpha_composite` if you want to
|
||||||
combine images with respect to their alpha channels.
|
combine images with respect to their alpha channels.
|
||||||
|
|
||||||
:param im: Source image or pixel value (integer or tuple).
|
:param im: Source image or pixel value (integer, float or tuple).
|
||||||
:param box: An optional 4-tuple giving the region to paste into.
|
:param box: An optional 4-tuple giving the region to paste into.
|
||||||
If a 2-tuple is used instead, it's treated as the upper left
|
If a 2-tuple is used instead, it's treated as the upper left
|
||||||
corner. If omitted or None, the source is pasted into the
|
corner. If omitted or None, the source is pasted into the
|
||||||
|
@ -2228,13 +2228,9 @@ class Image:
|
||||||
msg = "reducing_gap must be 1.0 or greater"
|
msg = "reducing_gap must be 1.0 or greater"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
|
||||||
size = cast("tuple[int, int]", tuple(size))
|
|
||||||
|
|
||||||
self.load()
|
self.load()
|
||||||
if box is None:
|
if box is None:
|
||||||
box = (0, 0) + self.size
|
box = (0, 0) + self.size
|
||||||
else:
|
|
||||||
box = cast("tuple[float, float, float, float]", tuple(box))
|
|
||||||
|
|
||||||
if self.size == size and box == (0, 0) + self.size:
|
if self.size == size and box == (0, 0) + self.size:
|
||||||
return self.copy()
|
return self.copy()
|
||||||
|
@ -2291,8 +2287,6 @@ class Image:
|
||||||
|
|
||||||
if box is None:
|
if box is None:
|
||||||
box = (0, 0) + self.size
|
box = (0, 0) + self.size
|
||||||
else:
|
|
||||||
box = cast("tuple[int, int, int, int]", tuple(box))
|
|
||||||
|
|
||||||
if factor == (1, 1) and box == (0, 0) + self.size:
|
if factor == (1, 1) and box == (0, 0) + self.size:
|
||||||
return self.copy()
|
return self.copy()
|
||||||
|
@ -2692,7 +2686,9 @@ class Image:
|
||||||
return
|
return
|
||||||
size = preserved_size
|
size = preserved_size
|
||||||
|
|
||||||
res = self.draft(None, (size[0] * reducing_gap, size[1] * reducing_gap)) # type: ignore[arg-type]
|
res = self.draft(
|
||||||
|
None, (int(size[0] * reducing_gap), int(size[1] * reducing_gap))
|
||||||
|
)
|
||||||
if res is not None:
|
if res is not None:
|
||||||
box = res[1]
|
box = res[1]
|
||||||
if box is None:
|
if box is None:
|
||||||
|
@ -2799,7 +2795,7 @@ class Image:
|
||||||
im.info = self.info.copy()
|
im.info = self.info.copy()
|
||||||
if method == Transform.MESH:
|
if method == Transform.MESH:
|
||||||
# list of quads
|
# list of quads
|
||||||
for box, quad in cast("Sequence[tuple[float, float]]", data):
|
for box, quad in data:
|
||||||
im.__transformer(
|
im.__transformer(
|
||||||
box, self, Transform.QUAD, quad, resample, fillcolor is None
|
box, self, Transform.QUAD, quad, resample, fillcolor is None
|
||||||
)
|
)
|
||||||
|
@ -2957,7 +2953,7 @@ class ImageTransformHandler:
|
||||||
self,
|
self,
|
||||||
size: tuple[int, int],
|
size: tuple[int, int],
|
||||||
image: Image,
|
image: Image,
|
||||||
**options: dict[str, str | int | tuple[int, ...] | list[int]] | int,
|
**options: str | int | tuple[int, ...] | list[int],
|
||||||
) -> Image:
|
) -> Image:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -456,14 +456,12 @@ class ImageDraw:
|
||||||
self.draw.draw_rectangle(right, ink, 1)
|
self.draw.draw_rectangle(right, ink, 1)
|
||||||
|
|
||||||
def _multiline_check(self, text: AnyStr) -> bool:
|
def _multiline_check(self, text: AnyStr) -> bool:
|
||||||
split_character = cast(AnyStr, "\n" if isinstance(text, str) else b"\n")
|
split_character = "\n" if isinstance(text, str) else b"\n"
|
||||||
|
|
||||||
return split_character in text
|
return split_character in text
|
||||||
|
|
||||||
def _multiline_split(self, text: AnyStr) -> list[AnyStr]:
|
def _multiline_split(self, text: AnyStr) -> list[AnyStr]:
|
||||||
split_character = cast(AnyStr, "\n" if isinstance(text, str) else b"\n")
|
return text.split("\n" if isinstance(text, str) else b"\n")
|
||||||
|
|
||||||
return text.split(split_character)
|
|
||||||
|
|
||||||
def _multiline_spacing(self, font, spacing, stroke_width):
|
def _multiline_spacing(self, font, spacing, stroke_width):
|
||||||
return (
|
return (
|
||||||
|
@ -477,7 +475,12 @@ class ImageDraw:
|
||||||
xy: tuple[float, float],
|
xy: tuple[float, float],
|
||||||
text: str,
|
text: str,
|
||||||
fill=None,
|
fill=None,
|
||||||
font: ImageFont.FreeTypeFont | ImageFont.ImageFont | None = None,
|
font: (
|
||||||
|
ImageFont.ImageFont
|
||||||
|
| ImageFont.FreeTypeFont
|
||||||
|
| ImageFont.TransposedFont
|
||||||
|
| None
|
||||||
|
) = None,
|
||||||
anchor=None,
|
anchor=None,
|
||||||
spacing=4,
|
spacing=4,
|
||||||
align="left",
|
align="left",
|
||||||
|
@ -597,9 +600,14 @@ class ImageDraw:
|
||||||
def multiline_text(
|
def multiline_text(
|
||||||
self,
|
self,
|
||||||
xy: tuple[float, float],
|
xy: tuple[float, float],
|
||||||
text,
|
text: str,
|
||||||
fill=None,
|
fill=None,
|
||||||
font=None,
|
font: (
|
||||||
|
ImageFont.ImageFont
|
||||||
|
| ImageFont.FreeTypeFont
|
||||||
|
| ImageFont.TransposedFont
|
||||||
|
| None
|
||||||
|
) = None,
|
||||||
anchor=None,
|
anchor=None,
|
||||||
spacing=4,
|
spacing=4,
|
||||||
align="left",
|
align="left",
|
||||||
|
@ -684,7 +692,12 @@ class ImageDraw:
|
||||||
def textlength(
|
def textlength(
|
||||||
self,
|
self,
|
||||||
text: str,
|
text: str,
|
||||||
font: ImageFont.FreeTypeFont | ImageFont.ImageFont | None = None,
|
font: (
|
||||||
|
ImageFont.ImageFont
|
||||||
|
| ImageFont.FreeTypeFont
|
||||||
|
| ImageFont.TransposedFont
|
||||||
|
| None
|
||||||
|
) = None,
|
||||||
direction=None,
|
direction=None,
|
||||||
features=None,
|
features=None,
|
||||||
language=None,
|
language=None,
|
||||||
|
|
|
@ -33,11 +33,11 @@ import sys
|
||||||
import warnings
|
import warnings
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import TYPE_CHECKING, BinaryIO
|
from typing import IO, TYPE_CHECKING, Any, BinaryIO
|
||||||
|
|
||||||
from . import Image
|
from . import Image
|
||||||
from ._typing import StrOrBytesPath
|
from ._typing import StrOrBytesPath
|
||||||
from ._util import is_directory, is_path
|
from ._util import is_path
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from . import ImageFile
|
from . import ImageFile
|
||||||
|
@ -61,7 +61,7 @@ except ImportError as ex:
|
||||||
core = DeferredError.new(ex)
|
core = DeferredError.new(ex)
|
||||||
|
|
||||||
|
|
||||||
def _string_length_check(text: str) -> None:
|
def _string_length_check(text: str | bytes | bytearray) -> None:
|
||||||
if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH:
|
if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH:
|
||||||
msg = "too many characters in string"
|
msg = "too many characters in string"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
@ -113,7 +113,7 @@ class ImageFont:
|
||||||
self._load_pilfont_data(fp, image)
|
self._load_pilfont_data(fp, image)
|
||||||
image.close()
|
image.close()
|
||||||
|
|
||||||
def _load_pilfont_data(self, file, image):
|
def _load_pilfont_data(self, file: IO[bytes], image: Image.Image) -> None:
|
||||||
# read PILfont header
|
# read PILfont header
|
||||||
if file.readline() != b"PILfont\n":
|
if file.readline() != b"PILfont\n":
|
||||||
msg = "Not a PILfont file"
|
msg = "Not a PILfont file"
|
||||||
|
@ -161,7 +161,7 @@ class ImageFont:
|
||||||
return self.font.getmask(text, mode)
|
return self.font.getmask(text, mode)
|
||||||
|
|
||||||
def getbbox(
|
def getbbox(
|
||||||
self, text: str, *args: object, **kwargs: object
|
self, text: str | bytes | bytearray, *args: Any, **kwargs: Any
|
||||||
) -> tuple[int, int, int, int]:
|
) -> tuple[int, int, int, int]:
|
||||||
"""
|
"""
|
||||||
Returns bounding box (in pixels) of given text.
|
Returns bounding box (in pixels) of given text.
|
||||||
|
@ -180,7 +180,9 @@ class ImageFont:
|
||||||
width, height = self.font.getsize(text)
|
width, height = self.font.getsize(text)
|
||||||
return 0, 0, width, height
|
return 0, 0, width, height
|
||||||
|
|
||||||
def getlength(self, text: str, *args: object, **kwargs: object) -> int:
|
def getlength(
|
||||||
|
self, text: str | bytes | bytearray, *args: Any, **kwargs: Any
|
||||||
|
) -> int:
|
||||||
"""
|
"""
|
||||||
Returns length (in pixels) of given text.
|
Returns length (in pixels) of given text.
|
||||||
This is the amount by which following text should be offset.
|
This is the amount by which following text should be offset.
|
||||||
|
@ -357,13 +359,13 @@ class FreeTypeFont:
|
||||||
def getbbox(
|
def getbbox(
|
||||||
self,
|
self,
|
||||||
text: str,
|
text: str,
|
||||||
mode="",
|
mode: str = "",
|
||||||
direction=None,
|
direction: str | None = None,
|
||||||
features=None,
|
features: str | None = None,
|
||||||
language=None,
|
language: str | None = None,
|
||||||
stroke_width=0,
|
stroke_width: float = 0,
|
||||||
anchor=None,
|
anchor: str | None = None,
|
||||||
) -> tuple[int, int, int, int]:
|
) -> tuple[float, float, float, float]:
|
||||||
"""
|
"""
|
||||||
Returns bounding box (in pixels) of given text relative to given anchor
|
Returns bounding box (in pixels) of given text relative to given anchor
|
||||||
when rendered in font with provided direction, features, and language.
|
when rendered in font with provided direction, features, and language.
|
||||||
|
@ -513,7 +515,7 @@ class FreeTypeFont:
|
||||||
|
|
||||||
def getmask2(
|
def getmask2(
|
||||||
self,
|
self,
|
||||||
text,
|
text: str,
|
||||||
mode="",
|
mode="",
|
||||||
direction=None,
|
direction=None,
|
||||||
features=None,
|
features=None,
|
||||||
|
@ -641,7 +643,7 @@ class FreeTypeFont:
|
||||||
layout_engine=layout_engine or self.layout_engine,
|
layout_engine=layout_engine or self.layout_engine,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_variation_names(self):
|
def get_variation_names(self) -> list[bytes]:
|
||||||
"""
|
"""
|
||||||
:returns: A list of the named styles in a variation font.
|
:returns: A list of the named styles in a variation font.
|
||||||
:exception OSError: If the font is not a variation font.
|
:exception OSError: If the font is not a variation font.
|
||||||
|
@ -683,10 +685,11 @@ class FreeTypeFont:
|
||||||
msg = "FreeType 2.9.1 or greater is required"
|
msg = "FreeType 2.9.1 or greater is required"
|
||||||
raise NotImplementedError(msg) from e
|
raise NotImplementedError(msg) from e
|
||||||
for axis in axes:
|
for axis in axes:
|
||||||
|
if axis["name"]:
|
||||||
axis["name"] = axis["name"].replace(b"\x00", b"")
|
axis["name"] = axis["name"].replace(b"\x00", b"")
|
||||||
return axes
|
return axes
|
||||||
|
|
||||||
def set_variation_by_axes(self, axes):
|
def set_variation_by_axes(self, axes: list[float]) -> None:
|
||||||
"""
|
"""
|
||||||
:param axes: A list of values for each axis.
|
:param axes: A list of values for each axis.
|
||||||
:exception OSError: If the font is not a variation font.
|
:exception OSError: If the font is not a variation font.
|
||||||
|
@ -731,7 +734,7 @@ class TransposedFont:
|
||||||
return 0, 0, height, width
|
return 0, 0, height, width
|
||||||
return 0, 0, width, height
|
return 0, 0, width, height
|
||||||
|
|
||||||
def getlength(self, text, *args, **kwargs):
|
def getlength(self, text: str, *args, **kwargs) -> float:
|
||||||
if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270):
|
if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270):
|
||||||
msg = "text length is undefined for text rotated by 90 or 270 degrees"
|
msg = "text length is undefined for text rotated by 90 or 270 degrees"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
@ -878,11 +881,9 @@ def load_path(filename: str | bytes) -> ImageFont:
|
||||||
:return: A font object.
|
:return: A font object.
|
||||||
:exception OSError: If the file could not be read.
|
:exception OSError: If the file could not be read.
|
||||||
"""
|
"""
|
||||||
for directory in sys.path:
|
|
||||||
if is_directory(directory):
|
|
||||||
assert isinstance(directory, str)
|
|
||||||
if not isinstance(filename, str):
|
if not isinstance(filename, str):
|
||||||
filename = filename.decode("utf-8")
|
filename = filename.decode("utf-8")
|
||||||
|
for directory in sys.path:
|
||||||
try:
|
try:
|
||||||
return load(os.path.join(directory, filename))
|
return load(os.path.join(directory, filename))
|
||||||
except OSError:
|
except OSError:
|
||||||
|
|
|
@ -425,7 +425,7 @@ class JpegImageFile(ImageFile.ImageFile):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def draft(
|
def draft(
|
||||||
self, mode: str, size: tuple[int, int]
|
self, mode: str | None, size: tuple[int, int]
|
||||||
) -> tuple[str, tuple[int, int, float, float]] | None:
|
) -> tuple[str, tuple[int, int, float, float]] | None:
|
||||||
if len(self.tile) != 1:
|
if len(self.tile) != 1:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from typing_extensions import Buffer
|
|
||||||
|
|
||||||
class ImagingCore:
|
class ImagingCore:
|
||||||
def __getattr__(self, name: str) -> Any: ...
|
def __getattr__(self, name: str) -> Any: ...
|
||||||
|
|
||||||
|
@ -14,5 +12,5 @@ class ImagingDraw:
|
||||||
class PixelAccess:
|
class PixelAccess:
|
||||||
def __getattr__(self, name: str) -> Any: ...
|
def __getattr__(self, name: str) -> Any: ...
|
||||||
|
|
||||||
def font(image, glyphdata: Buffer) -> ImagingFont: ...
|
def font(image, glyphdata: bytes) -> ImagingFont: ...
|
||||||
def __getattr__(name: str) -> Any: ...
|
def __getattr__(name: str) -> Any: ...
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
from typing import Any, TypedDict
|
from typing import Any, TypedDict
|
||||||
|
|
||||||
|
from . import _imaging
|
||||||
|
|
||||||
class _Axis(TypedDict):
|
class _Axis(TypedDict):
|
||||||
minimum: int | None
|
minimum: int | None
|
||||||
default: int | None
|
default: int | None
|
||||||
|
@ -37,21 +39,28 @@ class Font:
|
||||||
x_start=...,
|
x_start=...,
|
||||||
y_start=...,
|
y_start=...,
|
||||||
/,
|
/,
|
||||||
) -> tuple[Any, tuple[int, int]]: ...
|
) -> tuple[_imaging.ImagingCore, tuple[int, int]]: ...
|
||||||
def getsize(
|
def getsize(
|
||||||
self, string: str, mode=..., dir=..., features=..., lang=..., anchor=..., /
|
self,
|
||||||
|
string: str | bytes | bytearray,
|
||||||
|
mode=...,
|
||||||
|
dir=...,
|
||||||
|
features=...,
|
||||||
|
lang=...,
|
||||||
|
anchor=...,
|
||||||
|
/,
|
||||||
) -> tuple[tuple[int, int], tuple[int, int]]: ...
|
) -> tuple[tuple[int, int], tuple[int, int]]: ...
|
||||||
def getlength(
|
def getlength(
|
||||||
self, string: str, mode=..., dir=..., features=..., lang=..., /
|
self, string: str, mode=..., dir=..., features=..., lang=..., /
|
||||||
) -> int: ...
|
) -> float: ...
|
||||||
def getvarnames(self) -> list[str]: ...
|
def getvarnames(self) -> list[bytes]: ...
|
||||||
def getvaraxes(self) -> list[_Axis]: ...
|
def getvaraxes(self) -> list[_Axis] | None: ...
|
||||||
def setvarname(self, instance_index: int, /) -> None: ...
|
def setvarname(self, instance_index: int, /) -> None: ...
|
||||||
def setvaraxes(self, axes: list[float], /) -> None: ...
|
def setvaraxes(self, axes: list[float], /) -> None: ...
|
||||||
|
|
||||||
def getfont(
|
def getfont(
|
||||||
filename: str | bytes | bytearray,
|
filename: str | bytes,
|
||||||
size,
|
size: float,
|
||||||
index=...,
|
index=...,
|
||||||
encoding=...,
|
encoding=...,
|
||||||
font_bytes=...,
|
font_bytes=...,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user