Skip to content

Commit c7d805b

Browse files
srittauAlexWaygood
andauthored
[openpyxl] Annotate Worksheet and other items (#9892)
Co-authored-by: Alex Waygood <[email protected]>
1 parent a34da85 commit c7d805b

File tree

7 files changed

+186
-90
lines changed

7 files changed

+186
-90
lines changed

stubs/openpyxl/@tests/stubtest_allowlist.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ openpyxl.descriptors.slots.AutoSlotProperties.__new__
33

44
# Requires numpy to be installed
55
openpyxl.utils.dataframe
6+
7+
# Element can be imported from lxml or xml.etree, so the attributes can
8+
# differ at runtime.
9+
openpyxl.xml.functions.Element.*

stubs/openpyxl/openpyxl/cell/cell.pyi

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
from _typeshed import Incomplete
2-
from datetime import datetime
2+
from datetime import date, datetime, time, timedelta
3+
from decimal import Decimal
4+
from typing import overload
5+
from typing_extensions import TypeAlias
36

7+
from openpyxl.cell.rich_text import CellRichText
48
from openpyxl.comments.comments import Comment
59
from openpyxl.styles.cell_style import StyleArray
610
from openpyxl.styles.styleable import StyleableObject
11+
from openpyxl.worksheet.formula import ArrayFormula, DataTableFormula
712
from openpyxl.worksheet.hyperlink import Hyperlink
813
from openpyxl.worksheet.worksheet import Worksheet
914

15+
_CellValue: TypeAlias = ( # if numpy is installed also numpy bool and number types
16+
bool | float | Decimal | str | CellRichText | date | time | timedelta | DataTableFormula | ArrayFormula
17+
)
18+
1019
__docformat__: str
1120
TIME_TYPES: Incomplete
1221
TIME_FORMATS: Incomplete
@@ -49,14 +58,17 @@ class Cell(StyleableObject):
4958
def encoding(self) -> str: ...
5059
@property
5160
def base_date(self) -> datetime: ...
52-
def check_string(self, value: str): ...
61+
@overload
62+
def check_string(self, value: None) -> None: ...
63+
@overload
64+
def check_string(self, value: str | bytes) -> str: ...
5365
def check_error(self, value: object) -> str: ...
5466
@property
55-
def value(self) -> str | float | datetime | None: ...
67+
def value(self) -> _CellValue: ...
5668
@value.setter
57-
def value(self, value: str | float | datetime | None) -> None: ...
69+
def value(self, value: _CellValue | bytes | None) -> None: ...
5870
@property
59-
def internal_value(self) -> str | float | datetime | None: ...
71+
def internal_value(self) -> _CellValue: ...
6072
@property
6173
def hyperlink(self) -> Hyperlink | None: ...
6274
@hyperlink.setter
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from collections.abc import Iterable
2+
from typing import overload
3+
from typing_extensions import Self
4+
5+
from openpyxl.descriptors import Strict, String, Typed
6+
7+
class TextBlock(Strict):
8+
font: Typed
9+
text: String
10+
11+
def __init__(self, font: Typed, text: String) -> None: ...
12+
def __eq__(self, other: TextBlock) -> bool: ... # type: ignore[override]
13+
14+
class CellRichText(list[str | TextBlock]):
15+
@overload
16+
def __init__(self, __args: list[str] | list[TextBlock] | list[str | TextBlock] | tuple[str | TextBlock, ...]) -> None: ...
17+
@overload
18+
def __init__(self, *args: str | TextBlock) -> None: ...
19+
@classmethod
20+
def from_tree(cls, node) -> Self: ...
21+
def __add__(self, arg: Iterable[str | TextBlock]) -> CellRichText: ... # type: ignore[override]
22+
def append(self, arg: str | TextBlock) -> None: ...
23+
def extend(self, arg: Iterable[str | TextBlock]) -> None: ...
24+
def as_list(self) -> list[str]: ...
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
from _typeshed import Incomplete
21
from collections import defaultdict
2+
from typing import TypeVar
33

4-
class BoundDictionary(defaultdict[Incomplete, Incomplete]):
5-
reference: Incomplete
6-
def __init__(self, reference: Incomplete | None = ..., *args, **kw) -> None: ...
7-
def __getitem__(self, key): ...
4+
_KT = TypeVar("_KT")
5+
_VT = TypeVar("_VT")
6+
7+
class BoundDictionary(defaultdict[_KT, _VT]):
8+
reference: str | None
9+
def __init__(self, reference: str | None = None, *args, **kw) -> None: ...

stubs/openpyxl/openpyxl/worksheet/dimensions.pyi

Lines changed: 88 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,115 @@
1-
from _typeshed import Incomplete
1+
from _typeshed import Incomplete, Unused
2+
from collections.abc import Callable, Iterator
3+
from typing import ClassVar, Generic, TypeVar
4+
from typing_extensions import Self
25

36
from openpyxl.descriptors import Strict
7+
from openpyxl.descriptors.base import Alias, Bool, Float, Integer, String
48
from openpyxl.descriptors.serialisable import Serialisable
59
from openpyxl.styles.styleable import StyleableObject
610
from openpyxl.utils.bound_dictionary import BoundDictionary
11+
from openpyxl.worksheet.worksheet import Worksheet
12+
from openpyxl.xml.functions import Element
13+
14+
_DimT = TypeVar("_DimT", bound=Dimension)
715

816
class Dimension(Strict, StyleableObject):
9-
__fields__: Incomplete
10-
index: Incomplete
11-
hidden: Incomplete
12-
outlineLevel: Incomplete
13-
outline_level: Incomplete
14-
collapsed: Incomplete
15-
style: Incomplete
17+
__fields__: ClassVar[tuple[str, ...]]
18+
19+
index: Integer
20+
hidden: Bool
21+
outlineLevel: Integer
22+
outline_level: Alias
23+
collapsed: Bool
24+
style: Alias
25+
1626
def __init__(
17-
self, index, hidden, outlineLevel, collapsed, worksheet, visible: bool = ..., style: Incomplete | None = ...
27+
self,
28+
index: int,
29+
hidden: bool,
30+
outlineLevel: int | None,
31+
collapsed: bool,
32+
worksheet: Worksheet,
33+
visible: bool = True,
34+
style: Incomplete | None = None,
1835
) -> None: ...
19-
def __iter__(self): ...
20-
def __copy__(self): ...
36+
def __iter__(self) -> Iterator[tuple[str, str]]: ...
37+
def __copy__(self) -> Self: ...
2138

2239
class RowDimension(Dimension):
23-
__fields__: Incomplete
24-
r: Incomplete
25-
s: Incomplete
26-
ht: Incomplete
27-
height: Incomplete
28-
thickBot: Incomplete
29-
thickTop: Incomplete
40+
r: Alias
41+
s: Alias
42+
ht: Float
43+
height: Alias
44+
thickBot: Bool
45+
thickTop: Bool
46+
3047
def __init__(
3148
self,
32-
worksheet,
33-
index: int = ...,
34-
ht: Incomplete | None = ...,
35-
customHeight: Incomplete | None = ...,
36-
s: Incomplete | None = ...,
37-
customFormat: Incomplete | None = ...,
38-
hidden: bool = ...,
39-
outlineLevel: int = ...,
40-
outline_level: Incomplete | None = ...,
41-
collapsed: bool = ...,
42-
visible: Incomplete | None = ...,
43-
height: Incomplete | None = ...,
44-
r: Incomplete | None = ...,
45-
spans: Incomplete | None = ...,
46-
thickBot: Incomplete | None = ...,
47-
thickTop: Incomplete | None = ...,
48-
**kw,
49+
worksheet: Worksheet,
50+
index: int = 0,
51+
ht: Incomplete | None = None,
52+
customHeight: Incomplete | None = None,
53+
s: Incomplete | None = None,
54+
customFormat: Incomplete | None = None,
55+
hidden: bool = False,
56+
outlineLevel: int = 0,
57+
outline_level: Incomplete | None = None,
58+
collapsed: bool = False,
59+
visible: Incomplete | None = None,
60+
height: Incomplete | None = None,
61+
r: Incomplete | None = None,
62+
spans: Incomplete | None = None,
63+
thickBot: Incomplete | None = None,
64+
thickTop: Incomplete | None = None,
65+
**kw: Unused,
4966
) -> None: ...
5067
@property
51-
def customFormat(self): ...
68+
def customFormat(self) -> bool: ...
5269
@property
53-
def customHeight(self): ...
70+
def customHeight(self) -> bool: ...
5471

5572
class ColumnDimension(Dimension):
56-
width: Incomplete
57-
bestFit: Incomplete
58-
auto_size: Incomplete
59-
index: Incomplete
60-
min: Incomplete
61-
max: Incomplete
62-
collapsed: Incomplete
63-
__fields__: Incomplete
73+
width: Float
74+
bestFit: Bool
75+
auto_size: Alias
76+
index: String # type: ignore[assignment]
77+
min: Integer
78+
max: Integer
79+
collapsed: Bool
80+
6481
def __init__(
6582
self,
66-
worksheet,
67-
index: str = ...,
68-
width=...,
69-
bestFit: bool = ...,
70-
hidden: bool = ...,
71-
outlineLevel: int = ...,
72-
outline_level: Incomplete | None = ...,
73-
collapsed: bool = ...,
74-
style: Incomplete | None = ...,
75-
min: Incomplete | None = ...,
76-
max: Incomplete | None = ...,
77-
customWidth: bool = ...,
78-
visible: Incomplete | None = ...,
79-
auto_size: Incomplete | None = ...,
83+
worksheet: Worksheet,
84+
index: str = "A",
85+
width: int = ...,
86+
bestFit: bool = False,
87+
hidden: bool = False,
88+
outlineLevel: int = 0,
89+
outline_level: int | None = None,
90+
collapsed: bool = False,
91+
style: Incomplete | None = None,
92+
min: int | None = None,
93+
max: int | None = None,
94+
customWidth: bool = False,
95+
visible: bool | None = None,
96+
auto_size: bool | None = None,
8097
) -> None: ...
8198
@property
82-
def customWidth(self): ...
99+
def customWidth(self) -> bool: ...
83100
def reindex(self) -> None: ...
84-
def to_tree(self): ...
101+
def to_tree(self) -> Element | None: ...
85102

86-
class DimensionHolder(BoundDictionary):
87-
worksheet: Incomplete
88-
max_outline: Incomplete
89-
default_factory: Incomplete
90-
def __init__(self, worksheet, reference: str = ..., default_factory: Incomplete | None = ...) -> None: ...
91-
def group(self, start, end: Incomplete | None = ..., outline_level: int = ..., hidden: bool = ...) -> None: ...
92-
def to_tree(self): ...
103+
class DimensionHolder(BoundDictionary[str, _DimT], Generic[_DimT]):
104+
worksheet: Worksheet
105+
max_outline: int | None
106+
default_factory: Callable[[], _DimT] | None
107+
108+
def __init__(
109+
self, worksheet: Worksheet, reference: str = "index", default_factory: Callable[[], _DimT] | None = None
110+
) -> None: ...
111+
def group(self, start: str, end: str | None = None, outline_level: int = 1, hidden: bool = False) -> None: ...
112+
def to_tree(self) -> Element | None: ...
93113

94114
class SheetFormatProperties(Serialisable):
95115
tagname: str

stubs/openpyxl/openpyxl/worksheet/worksheet.pyi

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,34 @@
11
from _typeshed import Incomplete
22
from collections.abc import Generator, Iterable, Iterator
33
from datetime import datetime
4-
from typing import overload
5-
from typing_extensions import Literal
4+
from typing import Any, overload
5+
from typing_extensions import Final, Literal
66

7-
from openpyxl.cell.cell import Cell
7+
from openpyxl.cell.cell import Cell, _CellValue
8+
from openpyxl.formatting.formatting import ConditionalFormattingList
89
from openpyxl.workbook.child import _WorkbookChild
10+
from openpyxl.workbook.defined_name import DefinedNameDict
911
from openpyxl.workbook.workbook import Workbook
10-
from openpyxl.worksheet.cell_range import CellRange
11-
from openpyxl.worksheet.datavalidation import DataValidation
12+
from openpyxl.worksheet.cell_range import CellRange, MultiCellRange
13+
from openpyxl.worksheet.datavalidation import DataValidation, DataValidationList
14+
from openpyxl.worksheet.dimensions import ColumnDimension, DimensionHolder, RowDimension, SheetFormatProperties
15+
from openpyxl.worksheet.filters import AutoFilter
16+
from openpyxl.worksheet.page import PageMargins, PrintOptions, PrintPageSetup
17+
from openpyxl.worksheet.pagebreak import ColBreak, RowBreak
18+
from openpyxl.worksheet.properties import WorksheetProperties
19+
from openpyxl.worksheet.protection import SheetProtection
20+
from openpyxl.worksheet.scenario import ScenarioList
1221
from openpyxl.worksheet.table import Table, TableList
13-
from openpyxl.worksheet.views import SheetView
22+
from openpyxl.worksheet.views import SheetView, SheetViewList
1423

1524
class Worksheet(_WorkbookChild):
1625
mime_type: str
1726
BREAK_NONE: int
1827
BREAK_ROW: int
1928
BREAK_COLUMN: int
20-
SHEETSTATE_VISIBLE: str
21-
SHEETSTATE_HIDDEN: str
22-
SHEETSTATE_VERYHIDDEN: str
29+
SHEETSTATE_VISIBLE: Final = "visible"
30+
SHEETSTATE_HIDDEN: Final = "hidden"
31+
SHEETSTATE_VERYHIDDEN: Final = "veryHidden"
2332
PAPERSIZE_LETTER: str
2433
PAPERSIZE_LETTER_SMALL: str
2534
PAPERSIZE_TABLOID: str
@@ -33,6 +42,27 @@ class Worksheet(_WorkbookChild):
3342
PAPERSIZE_A5: str
3443
ORIENTATION_PORTRAIT: str
3544
ORIENTATION_LANDSCAPE: str
45+
46+
row_dimensions: DimensionHolder[RowDimension]
47+
column_dimensions: DimensionHolder[ColumnDimension]
48+
row_breaks: RowBreak
49+
col_breaks: ColBreak
50+
merged_cells: MultiCellRange
51+
data_validations: DataValidationList
52+
sheet_state: Literal["visible", "hidden", "veryHidden"]
53+
page_setup: PrintPageSetup
54+
print_options: PrintOptions
55+
page_margins: PageMargins
56+
views: SheetViewList
57+
protection: SheetProtection
58+
defined_names: DefinedNameDict
59+
auto_filter: AutoFilter
60+
conditional_formatting: ConditionalFormattingList
61+
legacy_drawing: Incomplete | None
62+
sheet_properties: WorksheetProperties
63+
sheet_format: SheetFormatProperties
64+
scenarios: ScenarioList
65+
3666
def __init__(self, parent: Workbook, title: str | None = ...) -> None: ...
3767
@property
3868
def sheet_view(self) -> SheetView: ...
@@ -49,7 +79,10 @@ class Worksheet(_WorkbookChild):
4979
@freeze_panes.setter
5080
def freeze_panes(self, topLeftCell: Incomplete | None = ...) -> None: ...
5181
def cell(self, row: int, column: int, value: str | None = ...) -> Cell: ...
52-
def __getitem__(self, key: str | int | slice) -> Cell | tuple[Cell, ...]: ...
82+
@overload
83+
def __getitem__(self, key: int | slice) -> tuple[Cell, ...]: ...
84+
@overload
85+
def __getitem__(self, key: str) -> Any: ... # Cell | tuple[Cell, ...]
5386
def __setitem__(self, key: str, value: str) -> None: ...
5487
def __iter__(self) -> Iterator[Cell]: ...
5588
def __delitem__(self, key: str) -> None: ...
@@ -102,9 +135,9 @@ class Worksheet(_WorkbookChild):
102135
values_only: bool,
103136
) -> Generator[tuple[Cell | str | float | datetime | None, ...], None, None]: ...
104137
@property
105-
def rows(self) -> Generator[Cell, None, None]: ...
138+
def rows(self) -> Generator[tuple[Cell, ...], None, None]: ...
106139
@property
107-
def values(self) -> Generator[str | float | datetime | None, None, None]: ...
140+
def values(self) -> Generator[tuple[_CellValue, ...], None, None]: ...
108141
@overload
109142
def iter_cols(
110143
self, min_col: int | None, max_col: int | None, min_row: int | None, max_row: int | None, values_only: Literal[True]

stubs/openpyxl/openpyxl/xml/functions.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from _typeshed import Incomplete
2+
from xml.etree.ElementTree import Element as Element # possibly also imported from lxml
23

34
NS_REGEX: Incomplete
45

0 commit comments

Comments
 (0)