From 24ae2815c6b30e37987c858860d32264fcae5dd5 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 4 Apr 2024 13:49:05 -0400 Subject: [PATCH 1/5] Use duck typing for workbook sheets --- stubs/openpyxl/openpyxl/workbook/workbook.pyi | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/stubs/openpyxl/openpyxl/workbook/workbook.pyi b/stubs/openpyxl/openpyxl/workbook/workbook.pyi index 5687dbc7aa64..a2b40d5999a2 100644 --- a/stubs/openpyxl/openpyxl/workbook/workbook.pyi +++ b/stubs/openpyxl/openpyxl/workbook/workbook.pyi @@ -1,7 +1,7 @@ from _typeshed import Incomplete, Unused from collections.abc import Iterator from datetime import datetime -from typing import Any, Final +from typing import Any, Final, Protocol, type_check_only from typing_extensions import TypeAlias, deprecated from zipfile import ZipFile @@ -17,6 +17,22 @@ from openpyxl.worksheet.worksheet import Worksheet _WorkbookWorksheet: TypeAlias = Worksheet | WriteOnlyWorksheet | ReadOnlyWorksheet _WorkbookSheet: TypeAlias = _WorkbookWorksheet | Chartsheet +# The type of worksheets in a workbook are the same as the `*Param` aliases above. +# However, because Worksheet adds a lots of attributes that other _WorkbookChild subclasses don't have +# (ReadOnlyWorksheet doesn't even inherit form it), this ends up being too disruptive +# to the typical usage of openpyxl where sheets are just Worksheets. +# Using Any may just loose too much type information and duck-typing +# from Worksheet works great here, even if the instance type might be wrong. +@type_check_only +class _WorksheetLike( + Worksheet, WriteOnlyWorksheet, ReadOnlyWorksheet, Protocol # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] +): ... + +@type_check_only +class _WorksheetOrChartsheetLike( + Chartsheet, _WorksheetLike, Protocol # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] +): ... + INTEGER_TYPES: Final[tuple[type[int]]] class Workbook: @@ -37,7 +53,7 @@ class Workbook: views: Incomplete # Useful as a reference of what "sheets" can be for other types # ExcelReader can add ReadOnlyWorksheet in read_only mode. - # _sheets: list[_WorkbookSheet] + # _sheets: list[_WorksheetOrChartsheetLike] def __init__(self, write_only: bool = False, iso_dates: bool = False) -> None: ... @property def epoch(self) -> datetime: ... @@ -52,7 +68,7 @@ class Workbook: @property def excel_base_date(self) -> datetime: ... @property - def active(self) -> _WorkbookSheet | None: ... + def active(self) -> _WorksheetOrChartsheetLike | None: ... @active.setter def active(self, value: Worksheet | Chartsheet | int) -> None: ... # read_only workbook cannot call this method @@ -66,18 +82,18 @@ class Workbook: def remove_sheet(self, worksheet: _WorkbookSheet) -> None: ... def create_chartsheet(self, title: str | _Decodable | None = None, index: int | None = None) -> Chartsheet: ... @deprecated("Use wb[sheetname]") - def get_sheet_by_name(self, name: str) -> _WorkbookSheet: ... + def get_sheet_by_name(self, name: str) -> _WorksheetOrChartsheetLike: ... def __contains__(self, key: str) -> bool: ... def index(self, worksheet: _WorkbookWorksheet) -> int: ... @deprecated("Use wb.index(worksheet)") def get_index(self, worksheet: _WorkbookWorksheet) -> int: ... - def __getitem__(self, key: str) -> _WorkbookSheet: ... + def __getitem__(self, key: str) -> _WorksheetOrChartsheetLike: ... def __delitem__(self, key: str) -> None: ... - def __iter__(self) -> Iterator[_WorkbookWorksheet]: ... + def __iter__(self) -> Iterator[_WorksheetLike]: ... @deprecated("Use wb.sheetnames") def get_sheet_names(self) -> list[str]: ... @property - def worksheets(self) -> list[_WorkbookWorksheet]: ... + def worksheets(self) -> list[_WorksheetLike]: ... @property def chartsheets(self) -> list[Chartsheet]: ... @property From 19e0b79de64ecd6a02ffa0bc7d3e4755c363e298 Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 4 Apr 2024 14:18:13 -0400 Subject: [PATCH 2/5] move type ignore 1 line up --- stubs/openpyxl/openpyxl/workbook/workbook.pyi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stubs/openpyxl/openpyxl/workbook/workbook.pyi b/stubs/openpyxl/openpyxl/workbook/workbook.pyi index a2b40d5999a2..0b203750e83d 100644 --- a/stubs/openpyxl/openpyxl/workbook/workbook.pyi +++ b/stubs/openpyxl/openpyxl/workbook/workbook.pyi @@ -24,13 +24,13 @@ _WorkbookSheet: TypeAlias = _WorkbookWorksheet | Chartsheet # Using Any may just loose too much type information and duck-typing # from Worksheet works great here, even if the instance type might be wrong. @type_check_only -class _WorksheetLike( - Worksheet, WriteOnlyWorksheet, ReadOnlyWorksheet, Protocol # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] +class _WorksheetLike( # type: ignore[misc] + Worksheet, WriteOnlyWorksheet, ReadOnlyWorksheet, Protocol # pyright: ignore[reportGeneralTypeIssues] ): ... @type_check_only -class _WorksheetOrChartsheetLike( - Chartsheet, _WorksheetLike, Protocol # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] +class _WorksheetOrChartsheetLike( # type: ignore[misc] + Chartsheet, _WorksheetLike, Protocol # pyright: ignore[reportGeneralTypeIssues] ): ... INTEGER_TYPES: Final[tuple[type[int]]] From d3e4a59a0e1902cd1ac11471244656913d1512e8 Mon Sep 17 00:00:00 2001 From: Avasam Date: Mon, 8 Apr 2024 12:39:15 -0400 Subject: [PATCH 3/5] PR comment adjustments --- stubs/openpyxl/openpyxl/workbook/workbook.pyi | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/stubs/openpyxl/openpyxl/workbook/workbook.pyi b/stubs/openpyxl/openpyxl/workbook/workbook.pyi index 0b203750e83d..20cf08d9695c 100644 --- a/stubs/openpyxl/openpyxl/workbook/workbook.pyi +++ b/stubs/openpyxl/openpyxl/workbook/workbook.pyi @@ -1,7 +1,7 @@ from _typeshed import Incomplete, Unused from collections.abc import Iterator from datetime import datetime -from typing import Any, Final, Protocol, type_check_only +from typing import Any, Final, type_check_only from typing_extensions import TypeAlias, deprecated from zipfile import ZipFile @@ -17,21 +17,18 @@ from openpyxl.worksheet.worksheet import Worksheet _WorkbookWorksheet: TypeAlias = Worksheet | WriteOnlyWorksheet | ReadOnlyWorksheet _WorkbookSheet: TypeAlias = _WorkbookWorksheet | Chartsheet -# The type of worksheets in a workbook are the same as the `*Param` aliases above. -# However, because Worksheet adds a lots of attributes that other _WorkbookChild subclasses don't have -# (ReadOnlyWorksheet doesn't even inherit form it), this ends up being too disruptive -# to the typical usage of openpyxl where sheets are just Worksheets. -# Using Any may just loose too much type information and duck-typing -# from Worksheet works great here, even if the instance type might be wrong. +# The type of worksheets in a workbook are the same as the aliases above. +# However, because Worksheet adds a lots of attributes that other _WorkbookChild subclasses +# don't have (ReadOnlyWorksheet doesn't even inherit from it), this ends up being too +# disruptive to the typical usage of openpyxl where sheets are just Worksheets. +# Using Any may just lose too much type information and duck-typing +# from Worksheet works great here. Allowing instance type check, even if direct +# type comparison might be wrong. @type_check_only -class _WorksheetLike( # type: ignore[misc] - Worksheet, WriteOnlyWorksheet, ReadOnlyWorksheet, Protocol # pyright: ignore[reportGeneralTypeIssues] -): ... +class _WorksheetLike(Worksheet, WriteOnlyWorksheet, ReadOnlyWorksheet): ... @type_check_only -class _WorksheetOrChartsheetLike( # type: ignore[misc] - Chartsheet, _WorksheetLike, Protocol # pyright: ignore[reportGeneralTypeIssues] -): ... +class _WorksheetOrChartsheetLike(Chartsheet, _WorksheetLike): ... INTEGER_TYPES: Final[tuple[type[int]]] From 3aaa0da1f9a44e109744af53ed9e9bf38d0cbadd Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 9 Apr 2024 20:41:49 -0400 Subject: [PATCH 4/5] Add ignores to incompatible definitions --- stubs/openpyxl/openpyxl/workbook/workbook.pyi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/stubs/openpyxl/openpyxl/workbook/workbook.pyi b/stubs/openpyxl/openpyxl/workbook/workbook.pyi index 20cf08d9695c..78bb4c028c46 100644 --- a/stubs/openpyxl/openpyxl/workbook/workbook.pyi +++ b/stubs/openpyxl/openpyxl/workbook/workbook.pyi @@ -25,10 +25,14 @@ _WorkbookSheet: TypeAlias = _WorkbookWorksheet | Chartsheet # from Worksheet works great here. Allowing instance type check, even if direct # type comparison might be wrong. @type_check_only -class _WorksheetLike(Worksheet, WriteOnlyWorksheet, ReadOnlyWorksheet): ... +class _WorksheetLike( # type: ignore[misc] # Incompatible definitions, expected, favor Worksheet + Worksheet, WriteOnlyWorksheet, ReadOnlyWorksheet +): ... @type_check_only -class _WorksheetOrChartsheetLike(Chartsheet, _WorksheetLike): ... +class _WorksheetOrChartsheetLike( # type: ignore[misc] # Incompatible definitions, expected, favor Worksheet + Chartsheet, _WorksheetLike +): ... INTEGER_TYPES: Final[tuple[type[int]]] From 1a79742b8fef5d87f6849b194e769021c6e93989 Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 9 Apr 2024 20:42:33 -0400 Subject: [PATCH 5/5] Remove redundant word --- stubs/openpyxl/openpyxl/workbook/workbook.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stubs/openpyxl/openpyxl/workbook/workbook.pyi b/stubs/openpyxl/openpyxl/workbook/workbook.pyi index 78bb4c028c46..9756e5f7a5b2 100644 --- a/stubs/openpyxl/openpyxl/workbook/workbook.pyi +++ b/stubs/openpyxl/openpyxl/workbook/workbook.pyi @@ -25,12 +25,12 @@ _WorkbookSheet: TypeAlias = _WorkbookWorksheet | Chartsheet # from Worksheet works great here. Allowing instance type check, even if direct # type comparison might be wrong. @type_check_only -class _WorksheetLike( # type: ignore[misc] # Incompatible definitions, expected, favor Worksheet +class _WorksheetLike( # type: ignore[misc] # Incompatible definitions, favor Worksheet Worksheet, WriteOnlyWorksheet, ReadOnlyWorksheet ): ... @type_check_only -class _WorksheetOrChartsheetLike( # type: ignore[misc] # Incompatible definitions, expected, favor Worksheet +class _WorksheetOrChartsheetLike( # type: ignore[misc] # Incompatible definitions, favor Worksheet Chartsheet, _WorksheetLike ): ...