diff --git a/stubs/openpyxl/openpyxl/cell/__init__.pyi b/stubs/openpyxl/openpyxl/cell/__init__.pyi index 725383e2bcd1..54641897e49a 100644 --- a/stubs/openpyxl/openpyxl/cell/__init__.pyi +++ b/stubs/openpyxl/openpyxl/cell/__init__.pyi @@ -22,3 +22,5 @@ _CellValue: TypeAlias = ( # noqa: Y047 # Used in other modules | ArrayFormula ) _AnyCellValue: TypeAlias = Any # Any of _CellValue # noqa: Y047 # Used in other modules + +_CellOrMergedCell: TypeAlias = Cell | MergedCell # noqa: Y047 # Used in other modules diff --git a/stubs/openpyxl/openpyxl/cell/_writer.pyi b/stubs/openpyxl/openpyxl/cell/_writer.pyi index a546a3241df0..da72488a1370 100644 --- a/stubs/openpyxl/openpyxl/cell/_writer.pyi +++ b/stubs/openpyxl/openpyxl/cell/_writer.pyi @@ -1,7 +1,9 @@ from _typeshed import Incomplete, Unused -def etree_write_cell(xf, worksheet: Unused, cell, styled: Incomplete | None = None) -> None: ... -def lxml_write_cell(xf, worksheet: Unused, cell, styled: bool = False) -> None: ... +from openpyxl.cell import _CellOrMergedCell + +def etree_write_cell(xf, worksheet: Unused, cell: _CellOrMergedCell, styled: Incomplete | None = None) -> None: ... +def lxml_write_cell(xf, worksheet: Unused, cell: _CellOrMergedCell, styled: bool = False) -> None: ... write_cell = lxml_write_cell write_cell = etree_write_cell diff --git a/stubs/openpyxl/openpyxl/cell/cell.pyi b/stubs/openpyxl/openpyxl/cell/cell.pyi index 9eb5ebc07178..dea71e03d8a8 100644 --- a/stubs/openpyxl/openpyxl/cell/cell.pyi +++ b/stubs/openpyxl/openpyxl/cell/cell.pyi @@ -3,7 +3,7 @@ from datetime import datetime from re import Pattern from typing import Final, Literal, overload -from openpyxl.cell import _CellValue, _TimeTypes +from openpyxl.cell import _CellOrMergedCell, _CellValue, _TimeTypes from openpyxl.comments.comments import Comment from openpyxl.compat.numbers import NUMERIC_TYPES as NUMERIC_TYPES # cell numeric types from openpyxl.styles.cell_style import StyleArray @@ -75,7 +75,7 @@ class Cell(StyleableObject): def hyperlink(self, val: Hyperlink | str | None) -> None: ... @property def is_date(self) -> bool: ... - def offset(self, row: int = 0, column: int = 0) -> Cell: ... + def offset(self, row: int = 0, column: int = 0) -> _CellOrMergedCell: ... @property def comment(self) -> Comment | None: ... @comment.setter diff --git a/stubs/openpyxl/openpyxl/comments/comment_sheet.pyi b/stubs/openpyxl/openpyxl/comments/comment_sheet.pyi index f7fd4b59ee50..f7069a43bd03 100644 --- a/stubs/openpyxl/openpyxl/comments/comment_sheet.pyi +++ b/stubs/openpyxl/openpyxl/comments/comment_sheet.pyi @@ -3,6 +3,7 @@ from collections.abc import Generator from typing import ClassVar, Literal, overload from typing_extensions import TypeAlias +from openpyxl.cell import _CellOrMergedCell from openpyxl.cell.text import Text from openpyxl.comments.author import AuthorList from openpyxl.comments.comments import Comment @@ -101,7 +102,7 @@ class CommentRecord(Serialisable): width: int = 144, ) -> None: ... @classmethod - def from_cell(cls, cell): ... + def from_cell(cls, cell: _CellOrMergedCell): ... @property def content(self) -> str: ... diff --git a/stubs/openpyxl/openpyxl/worksheet/_read_only.pyi b/stubs/openpyxl/openpyxl/worksheet/_read_only.pyi index d5a32d36a8e7..0579afc366a4 100644 --- a/stubs/openpyxl/openpyxl/worksheet/_read_only.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/_read_only.pyi @@ -1,10 +1,8 @@ from _typeshed import SupportsGetItem -from collections.abc import Generator, Iterator -from typing import Any, overload +from collections.abc import Generator from openpyxl import _VisibilityType -from openpyxl.cell import _CellValue -from openpyxl.cell.cell import Cell +from openpyxl.cell import _CellOrMergedCell, _CellValue from openpyxl.utils.cell import _RangeBoundariesTuple from openpyxl.workbook.workbook import Workbook from openpyxl.worksheet.worksheet import Worksheet @@ -21,16 +19,9 @@ class ReadOnlyWorksheet: # Same as Worksheet.rows # https://github.com/python/mypy/issues/6700 @property - def rows(self) -> Generator[tuple[Cell, ...], None, None]: ... - # From Worksheet.__getitem__ - @overload - def __getitem__(self, key: int) -> tuple[Cell, ...]: ... - @overload - def __getitem__(self, key: slice) -> tuple[Any, ...]: ... # tuple[AnyOf[Cell, tuple[Cell, ...]]] - @overload - def __getitem__(self, key: str) -> Any: ... # AnyOf[Cell, tuple[Cell, ...], tuple[tuple[Cell, ...], ...]] - # From Worksheet.__iter__ - def __iter__(self) -> Iterator[tuple[Cell, ...]]: ... + def rows(self) -> Generator[tuple[_CellOrMergedCell, ...], None, None]: ... + __getitem__ = Worksheet.__getitem__ + __iter__ = Worksheet.__iter__ parent: Workbook title: str sheet_state: _VisibilityType diff --git a/stubs/openpyxl/openpyxl/worksheet/_reader.pyi b/stubs/openpyxl/openpyxl/worksheet/_reader.pyi index feec1c6c5dcc..420fc3dac2d9 100644 --- a/stubs/openpyxl/openpyxl/worksheet/_reader.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/_reader.pyi @@ -4,8 +4,7 @@ from datetime import datetime from typing import Final from xml.etree.ElementTree import _FileRead -from openpyxl.cell import _AnyCellValue -from openpyxl.cell.cell import Cell +from openpyxl.cell import _AnyCellValue, _CellOrMergedCell from openpyxl.cell.rich_text import CellRichText from openpyxl.descriptors.serialisable import _ChildSerialisableTreeElement, _SerialisableTreeElement from openpyxl.formula.translate import Translator @@ -111,7 +110,7 @@ class WorksheetReader: def bind_tables(self) -> None: ... def bind_merged_cells(self) -> None: ... def bind_hyperlinks(self) -> None: ... - def normalize_merged_cell_link(self, coord: str) -> Cell | None: ... + def normalize_merged_cell_link(self, coord: str) -> _CellOrMergedCell | None: ... def bind_col_dimensions(self) -> None: ... def bind_row_dimensions(self) -> None: ... def bind_properties(self) -> None: ... diff --git a/stubs/openpyxl/openpyxl/worksheet/_writer.pyi b/stubs/openpyxl/openpyxl/worksheet/_writer.pyi index 06059186e2c8..6261170ee21d 100644 --- a/stubs/openpyxl/openpyxl/worksheet/_writer.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/_writer.pyi @@ -1,8 +1,9 @@ from _typeshed import Incomplete, ReadableBuffer, StrPath, Unused -from collections.abc import Generator +from collections.abc import Generator, Iterable from typing import Protocol from typing_extensions import TypeAlias +from openpyxl.cell import _CellOrMergedCell from openpyxl.worksheet._write_only import WriteOnlyWorksheet from openpyxl.worksheet.worksheet import Worksheet @@ -30,9 +31,9 @@ class WorksheetWriter: def write_views(self) -> None: ... def write_cols(self) -> None: ... def write_top(self) -> None: ... - def rows(self) -> list[tuple[int, list[Incomplete]]]: ... + def rows(self) -> list[tuple[int, list[_CellOrMergedCell]]]: ... def write_rows(self) -> None: ... - def write_row(self, xf, row, row_idx) -> None: ... + def write_row(self, xf, row: Iterable[_CellOrMergedCell], row_idx) -> None: ... def write_protection(self) -> None: ... def write_scenarios(self) -> None: ... def write_filter(self) -> None: ... diff --git a/stubs/openpyxl/openpyxl/worksheet/merge.pyi b/stubs/openpyxl/openpyxl/worksheet/merge.pyi index bbf8c225be9e..7faa6cfaea71 100644 --- a/stubs/openpyxl/openpyxl/worksheet/merge.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/merge.pyi @@ -1,6 +1,7 @@ from _typeshed import Incomplete, Unused from typing import ClassVar +from openpyxl.cell import _CellOrMergedCell from openpyxl.descriptors.serialisable import Serialisable from openpyxl.worksheet.worksheet import Worksheet @@ -29,7 +30,7 @@ class MergeCells(Serialisable): class MergedCellRange(CellRange): ws: Worksheet - start_cell: Incomplete + start_cell: _CellOrMergedCell def __init__(self, worksheet: Worksheet, coord) -> None: ... def format(self) -> None: ... def __contains__(self, coord: str) -> bool: ... diff --git a/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi b/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi index 0fd8a84ef379..6b40a85a7be6 100644 --- a/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi @@ -6,7 +6,7 @@ from typing import Any, Final, Literal, NoReturn, overload from typing_extensions import deprecated from openpyxl import _Decodable, _VisibilityType -from openpyxl.cell import _CellValue +from openpyxl.cell import _CellOrMergedCell, _CellValue from openpyxl.cell.cell import Cell from openpyxl.chart._chart import ChartBase from openpyxl.drawing.image import Image @@ -51,6 +51,7 @@ class Worksheet(_WorkbookChild): ORIENTATION_PORTRAIT: Final = "portrait" ORIENTATION_LANDSCAPE: Final = "landscape" + _cells: dict[tuple[int, int], _CellOrMergedCell] # private but very useful to understand typing row_dimensions: DimensionHolder[int, RowDimension] column_dimensions: DimensionHolder[str, ColumnDimension] row_breaks: RowBreak @@ -85,19 +86,21 @@ class Worksheet(_WorkbookChild): @property def freeze_panes(self) -> str | None: ... @freeze_panes.setter - def freeze_panes(self, topLeftCell: str | Cell | None = ...) -> None: ... - def cell(self, row: int, column: int, value: _CellValue | None = None) -> Cell: ... + def freeze_panes(self, topLeftCell: str | Cell | None = None) -> None: ... + def cell(self, row: int, column: int, value: _CellValue | None = None) -> _CellOrMergedCell: ... # An int is necessarily a row selection @overload - def __getitem__(self, key: int) -> tuple[Cell, ...]: ... + def __getitem__(self, key: int) -> tuple[_CellOrMergedCell, ...]: ... # A slice is necessarily a row or rows, even if targetting a single cell @overload - def __getitem__(self, key: slice) -> tuple[Any, ...]: ... # tuple[AnyOf[Cell, tuple[Cell, ...]]] + def __getitem__(self, key: slice) -> tuple[Any, ...]: ... # tuple[AnyOf[_CellOrMergedCell, tuple[_CellOrMergedCell, ...]]] # A str could be an individual cell, row, column or full range @overload - def __getitem__(self, key: str) -> Any: ... # AnyOf[Cell, tuple[Cell, ...], tuple[tuple[Cell, ...], ...]] + def __getitem__( + self, key: str + ) -> Any: ... # AnyOf[_CellOrMergedCell, tuple[_CellOrMergedCell, ...], tuple[tuple[_CellOrMergedCell, ...], ...]] def __setitem__(self, key: str, value: _CellValue) -> None: ... - def __iter__(self) -> Iterator[tuple[Cell, ...]]: ... + def __iter__(self) -> Iterator[tuple[_CellOrMergedCell, ...]]: ... def __delitem__(self, key: str) -> None: ... @property def min_row(self) -> int: ... @@ -132,11 +135,13 @@ class Worksheet(_WorkbookChild): min_col: int | None = None, max_col: int | None = None, values_only: Literal[False] = False, - ) -> Generator[tuple[Cell, ...], None, None]: ... + ) -> Generator[tuple[_CellOrMergedCell, ...], None, None]: ... @overload def iter_rows( self, min_row: int | None, max_row: int | None, min_col: int | None, max_col: int | None, values_only: bool - ) -> Generator[tuple[Cell, ...], None, None] | Generator[tuple[str | float | datetime | None, ...], None, None]: ... + ) -> ( + Generator[tuple[_CellOrMergedCell, ...], None, None] | Generator[tuple[str | float | datetime | None, ...], None, None] + ): ... @overload def iter_rows( self, @@ -146,9 +151,11 @@ class Worksheet(_WorkbookChild): max_col: int | None = None, *, values_only: bool, - ) -> Generator[tuple[Cell, ...], None, None] | Generator[tuple[str | float | datetime | None, ...], None, None]: ... + ) -> ( + Generator[tuple[_CellOrMergedCell, ...], None, None] | Generator[tuple[str | float | datetime | None, ...], None, None] + ): ... @property - def rows(self) -> Generator[tuple[Cell, ...], None, None]: ... + def rows(self) -> Generator[tuple[_CellOrMergedCell, ...], None, None]: ... @property def values(self) -> Generator[tuple[_CellValue | None, ...]]: ... @overload @@ -173,11 +180,13 @@ class Worksheet(_WorkbookChild): min_row: int | None = None, max_row: int | None = None, values_only: Literal[False] = False, - ) -> Generator[tuple[Cell, ...], None, None]: ... + ) -> Generator[tuple[_CellOrMergedCell, ...], None, None]: ... @overload def iter_cols( self, min_col: int | None, max_col: int | None, min_row: int | None, max_row: int | None, values_only: bool - ) -> Generator[tuple[Cell, ...], None, None] | Generator[tuple[str | float | datetime | None, ...], None, None]: ... + ) -> ( + Generator[tuple[_CellOrMergedCell, ...], None, None] | Generator[tuple[str | float | datetime | None, ...], None, None] + ): ... @overload def iter_cols( self, @@ -187,9 +196,11 @@ class Worksheet(_WorkbookChild): max_row: int | None = None, *, values_only: bool, - ) -> Generator[tuple[Cell, ...], None, None] | Generator[tuple[str | float | datetime | None, ...], None, None]: ... + ) -> ( + Generator[tuple[_CellOrMergedCell, ...], None, None] | Generator[tuple[str | float | datetime | None, ...], None, None] + ): ... @property - def columns(self) -> Generator[tuple[Cell, ...], None, None]: ... + def columns(self) -> Generator[tuple[_CellOrMergedCell, ...], None, None]: ... @property def column_groups(self) -> list[str]: ... def set_printer_settings( @@ -241,11 +252,11 @@ class Worksheet(_WorkbookChild): def append( self, iterable: ( - list[Incomplete] - | tuple[Incomplete, ...] + list[Any] # lists are invariant, but any subtype or union will do + | tuple[_CellOrMergedCell | str | float | datetime | None, ...] | range - | GeneratorType[Incomplete, object, object] - | dict[int | str, Incomplete] + | GeneratorType[_CellOrMergedCell | str | float | datetime | None, object, object] + | dict[int | str, str | float | datetime | None] ), ) -> None: ... def insert_rows(self, idx: int, amount: int = 1) -> None: ...