From 8f40d8b701d0b0ce3744db4117c1c3b01ed7ab72 Mon Sep 17 00:00:00 2001 From: donBarbos Date: Tue, 12 Aug 2025 12:10:22 +0400 Subject: [PATCH] [fpdf2] Update to 2.8.4 Closes: #14560 --- stubs/fpdf2/METADATA.toml | 2 +- stubs/fpdf2/fpdf/enums.pyi | 101 ++++++++++++++++++++++++++++++---- stubs/fpdf2/fpdf/fonts.pyi | 1 + stubs/fpdf2/fpdf/fpdf.pyi | 2 +- stubs/fpdf2/fpdf/html.pyi | 16 +++--- stubs/fpdf2/fpdf/svg.pyi | 15 +++-- stubs/fpdf2/fpdf/syntax.pyi | 1 + stubs/fpdf2/fpdf/table.pyi | 1 - stubs/fpdf2/fpdf/template.pyi | 2 +- 9 files changed, 115 insertions(+), 26 deletions(-) diff --git a/stubs/fpdf2/METADATA.toml b/stubs/fpdf2/METADATA.toml index 8ffd02df0c12..99ca1632cb80 100644 --- a/stubs/fpdf2/METADATA.toml +++ b/stubs/fpdf2/METADATA.toml @@ -1,4 +1,4 @@ -version = "2.8.3" +version = "2.8.4" upstream_repository = "https://github.com/PyFPDF/fpdf2" requires = ["Pillow>=10.3.0"] diff --git a/stubs/fpdf2/fpdf/enums.pyi b/stubs/fpdf2/fpdf/enums.pyi index f9f7fb8ce4ee..5c11f04e31ce 100644 --- a/stubs/fpdf2/fpdf/enums.pyi +++ b/stubs/fpdf2/fpdf/enums.pyi @@ -1,9 +1,15 @@ +from abc import ABC, abstractmethod +from collections.abc import Sequence +from dataclasses import dataclass from enum import Enum, Flag, IntEnum, IntFlag -from typing import Literal +from typing import Final, Literal from typing_extensions import Self, TypeAlias +from .drawing import DeviceCMYK, DeviceGray, DeviceRGB from .syntax import Name +_Color: TypeAlias = str | int | Sequence[int] | DeviceCMYK | DeviceGray | DeviceRGB + class SignatureFlag(IntEnum): SIGNATURES_EXIST = 1 APPEND_ONLY = 2 @@ -68,15 +74,6 @@ class MethodReturnValue(CoerciveIntFlag): LINES = 2 HEIGHT = 4 -class TableBordersLayout(CoerciveEnum): - ALL = "ALL" - NONE = "NONE" - INTERNAL = "INTERNAL" - MINIMAL = "MINIMAL" - HORIZONTAL_LINES = "HORIZONTAL_LINES" - NO_HORIZONTAL_LINES = "NO_HORIZONTAL_LINES" - SINGLE_TOP_LINE = "SINGLE_TOP_LINE" - class CellBordersLayout(CoerciveIntFlag): NONE = 0 LEFT = 1 @@ -86,6 +83,90 @@ class CellBordersLayout(CoerciveIntFlag): ALL = 15 INHERIT = 16 +@dataclass +class TableBorderStyle: + thickness: float | None = None + color: int | tuple[int, int, int] | None = None + dash: float | None = None + gap: float = 0.0 + phase: float = 0.0 + + @staticmethod + def from_bool(should_draw: TableBorderStyle | bool | None) -> TableBorderStyle: ... + @property + def dash_dict(self) -> dict[str, float | None]: ... + def changes_stroke(self, pdf) -> bool: ... + def should_render(self) -> bool: ... + def get_change_stroke_commands(self, scale: float) -> list[str]: ... + @staticmethod + def get_line_command(x1: float, y1: float, x2: float, y2: float) -> list[str]: ... + def get_draw_commands(self, pdf, x1: float, y1: float, x2: float, y2: float) -> list[str]: ... + +@dataclass +class TableCellStyle: + left: bool | TableBorderStyle = False + bottom: bool | TableBorderStyle = False + right: bool | TableBorderStyle = False + top: bool | TableBorderStyle = False + + @staticmethod + def get_change_fill_color_command(color: _Color | None) -> list[str]: ... + def get_draw_commands( + self, pdf, x1: float, y1: float, x2: float, y2: float, fill_color: _Color | None = None + ) -> list[str]: ... + def override_cell_border(self, cell_border: CellBordersLayout) -> Self: ... + def draw_cell_border(self, pdf, x1: float, y1: float, x2: float, y2: float, fill_color: _Color | None = None) -> None: ... + +class TableBordersLayout(ABC): + ALL: Final[TableBordersLayoutAll] + NONE: Final[TableBordersLayoutNone] + INTERNAL: Final[TableBordersLayoutInternal] + MINIMAL: Final[TableBordersLayoutMinimal] + HORIZONTAL_LINES: Final[TableBordersLayoutHorizontalLines] + NO_HORIZONTAL_LINES: Final[TableBordersLayoutNoHorizontalLines] + SINGLE_TOP_LINE: Final[TableBordersLayoutSingleTopLine] + @abstractmethod + def cell_style_getter( + self, row_idx: int, col_idx: int, col_pos: int, num_heading_rows: int, num_rows: int, num_col_idx: int, num_col_pos: int + ) -> TableCellStyle: ... + @classmethod + def coerce(cls, value: Self | str) -> Self: ... + +class TableBordersLayoutAll(TableBordersLayout): + def cell_style_getter( + self, row_idx: int, col_idx: int, col_pos: int, num_heading_rows: int, num_rows: int, num_col_idx: int, num_col_pos: int + ) -> TableCellStyle: ... + +class TableBordersLayoutNone(TableBordersLayout): + def cell_style_getter( + self, row_idx: int, col_idx: int, col_pos: int, num_heading_rows: int, num_rows: int, num_col_idx: int, num_col_pos: int + ) -> TableCellStyle: ... + +class TableBordersLayoutInternal(TableBordersLayout): + def cell_style_getter( + self, row_idx: int, col_idx: int, col_pos: int, num_heading_rows: int, num_rows: int, num_col_idx: int, num_col_pos: int + ) -> TableCellStyle: ... + +class TableBordersLayoutMinimal(TableBordersLayout): + def cell_style_getter( + self, row_idx: int, col_idx: int, col_pos: int, num_heading_rows: int, num_rows: int, num_col_idx: int, num_col_pos: int + ) -> TableCellStyle: ... + +class TableBordersLayoutHorizontalLines(TableBordersLayout): + def cell_style_getter( + self, row_idx: int, col_idx: int, col_pos: int, num_heading_rows: int, num_rows: int, num_col_idx: int, num_col_pos: int + ) -> TableCellStyle: ... + +class TableBordersLayoutNoHorizontalLines(TableBordersLayout): + def cell_style_getter( + self, row_idx: int, col_idx: int, col_pos: int, num_heading_rows: int, num_rows: int, num_col_idx: int, num_col_pos: int + ) -> TableCellStyle: ... + +class TableBordersLayoutSingleTopLine(TableBordersLayout): + def cell_style_getter( + self, row_idx: int, col_idx: int, col_pos: int, num_heading_rows: int, num_rows: int, num_col_idx: int, num_col_pos: int + ) -> TableCellStyle: ... + class TableCellFillMode(CoerciveEnum): NONE = "NONE" ALL = "ALL" diff --git a/stubs/fpdf2/fpdf/fonts.pyi b/stubs/fpdf2/fpdf/fonts.pyi index ee0502b493dc..b508d6d97a26 100644 --- a/stubs/fpdf2/fpdf/fonts.pyi +++ b/stubs/fpdf2/fpdf/fonts.pyi @@ -114,6 +114,7 @@ class TTFFont: subset: SubsetMap hbfont: HarfBuzzFont | None # Not always defined. def __init__(self, fpdf, font_file_path, fontkey: str, style: int) -> None: ... + def __deepcopy__(self, memo) -> Self: ... def close(self) -> None: ... def get_text_width(self, text: str, font_size_pt: int, text_shaping_params): ... def shaped_text_width(self, text: str, font_size_pt: int, text_shaping_params): ... diff --git a/stubs/fpdf2/fpdf/fpdf.pyi b/stubs/fpdf2/fpdf/fpdf.pyi index 67832cb7fbf2..820ba83c6b55 100644 --- a/stubs/fpdf2/fpdf/fpdf.pyi +++ b/stubs/fpdf2/fpdf/fpdf.pyi @@ -109,7 +109,7 @@ _FontStyles: TypeAlias = Literal[ ] FPDF_VERSION: Final[str] -PAGE_FORMATS: dict[_Format, tuple[float, float]] +PAGE_FORMATS: Final[dict[_Format, tuple[float, float]]] class ToCPlaceholder(NamedTuple): render_function: Callable[[FPDF, list[OutlineSection]], object] diff --git a/stubs/fpdf2/fpdf/html.pyi b/stubs/fpdf2/fpdf/html.pyi index 9cf64f1e6163..8225d7177721 100644 --- a/stubs/fpdf2/fpdf/html.pyi +++ b/stubs/fpdf2/fpdf/html.pyi @@ -7,7 +7,7 @@ from typing_extensions import TypeAlias from fpdf import FPDF -from .enums import TextEmphasis +from .enums import Align, TextEmphasis from .fonts import FontFace from .table import Row, Table @@ -17,8 +17,10 @@ __copyright__: Final[str] _OLType: TypeAlias = Literal["1", "a", "A", "I", "i"] LOGGER: Logger -BULLET_WIN1252: Final[str] -DEGREE_WIN1252: Final[str] +MESSAGE_WAITING_WIN1252: Final = "\x95" +BULLET_UNICODE: Final = "•" +DEGREE_SIGN_WIN1252: Final = "\xb0" +RING_OPERATOR_UNICODE: Final = "∘" HEADING_TAGS: Final[tuple[str, ...]] DEFAULT_TAG_STYLES: Final[dict[str, FontFace]] INLINE_TAGS: Final[tuple[str, ...]] @@ -49,10 +51,10 @@ class HTML2FPDF(HTMLParser): follows_trailing_space: bool follows_heading: bool href: str - align: str + align: float | Align | None indent: int line_height_stack: list[Incomplete] - ol_type: list[_OLType] + ol_type: dict[int, _OLType] bullet: list[Incomplete] heading_level: Incomplete | None render_title_tag: bool @@ -71,7 +73,7 @@ class HTML2FPDF(HTMLParser): li_tag_indent: int | None = None, dd_tag_indent: int | None = None, table_line_separators: bool = False, - ul_bullet_char: str = "\x95", + ul_bullet_char: str = "disc", li_prefix_color: tuple[int, int, int] = (190, 0, 0), heading_sizes: SupportsKeysAndGetItem[str, int] | Iterable[tuple[str, int]] | None = None, pre_code_font: str | None = None, @@ -88,7 +90,7 @@ class HTML2FPDF(HTMLParser): def render_toc(self, pdf, outline) -> None: ... def error(self, message: str) -> None: ... -def ul_prefix(ul_type: str) -> str: ... +def ul_prefix(ul_type: str, is_ttf_font: bool | None) -> str: ... def ol_prefix(ol_type: _OLType, index: int) -> str: ... class HTMLMixin: diff --git a/stubs/fpdf2/fpdf/svg.pyi b/stubs/fpdf2/fpdf/svg.pyi index 3f98d58aafdf..2a2eb78fb606 100644 --- a/stubs/fpdf2/fpdf/svg.pyi +++ b/stubs/fpdf2/fpdf/svg.pyi @@ -2,7 +2,7 @@ from _typeshed import Incomplete, Unused from collections.abc import Callable from logging import Logger from re import Pattern -from typing import Literal, NamedTuple, overload +from typing import Final, Literal, NamedTuple, Protocol, TypeVar, overload, type_check_only from ._fonttools_shims import BasePen, _TTGlyphSet from .drawing import ClippingPath, PaintedPath @@ -10,13 +10,18 @@ from .fpdf import FPDF from .image_datastructures import ImageCache LOGGER: Logger - __pdoc__: dict[str, bool] -def force_nodocument(item): ... +@type_check_only +class _HasQualname(Protocol): + __qualname__: str + +_T = TypeVar("_T", bound=_HasQualname) + +def force_nodocument(item: _T) -> _T: ... -NUMBER_SPLIT: Pattern[str] -TRANSFORM_GETTER: Pattern[str] +NUMBER_SPLIT: Final[Pattern[str]] +TRANSFORM_GETTER: Final[Pattern[str]] class Percent(float): ... diff --git a/stubs/fpdf2/fpdf/syntax.pyi b/stubs/fpdf2/fpdf/syntax.pyi index a6005e9e4c52..215db48473d1 100644 --- a/stubs/fpdf2/fpdf/syntax.pyi +++ b/stubs/fpdf2/fpdf/syntax.pyi @@ -21,6 +21,7 @@ def create_dictionary_string( def create_list_string(list_): ... def iobj_ref(n): ... def create_stream(stream: str | bytes | bytearray, encryption_handler: StandardSecurityHandler | None = None, obj_id=None): ... +def wrap_in_local_context(draw_commands: list[str]) -> list[str]: ... class Raw(str): ... diff --git a/stubs/fpdf2/fpdf/table.pyi b/stubs/fpdf2/fpdf/table.pyi index 55ec102ed504..6a05934bdd70 100644 --- a/stubs/fpdf2/fpdf/table.pyi +++ b/stubs/fpdf2/fpdf/table.pyi @@ -58,7 +58,6 @@ class Table: self, cells: Iterable[str] = (), style: FontFace | None = None, v_align: VAlign | str | None = None, min_height=None ) -> Row: ... def render(self) -> None: ... - def get_cell_border(self, i: int, j: int, cell: Cell) -> str | Literal[0, 1]: ... class Row: cells: list[Cell] diff --git a/stubs/fpdf2/fpdf/template.pyi b/stubs/fpdf2/fpdf/template.pyi index 4c94913b3356..41d5f9d55308 100644 --- a/stubs/fpdf2/fpdf/template.pyi +++ b/stubs/fpdf2/fpdf/template.pyi @@ -22,7 +22,7 @@ class FlexTemplate: set: Any def __contains__(self, name): ... def __getitem__(self, name): ... - def split_multicell(self, text, element_name): ... + def split_multicell(self, text: str, element_name: str) -> list[str]: ... def render(self, offsetx: float = 0.0, offsety: float = 0.0, rotate: float = 0.0, scale: float = 1.0): ... class Template(FlexTemplate):