diff --git a/stubs/openpyxl/@tests/stubtest_allowlist.txt b/stubs/openpyxl/@tests/stubtest_allowlist.txt index cf28e9a4b..1a9bcaf7b 100644 --- a/stubs/openpyxl/@tests/stubtest_allowlist.txt +++ b/stubs/openpyxl/@tests/stubtest_allowlist.txt @@ -1,7 +1,3 @@ -# Loop variables leaked in global scope -openpyxl.utils.cell.col -openpyxl.utils.cell.i - # Unintended re-export from star-import openpyxl.chart.marker.DRAWING_NS openpyxl.chart.marker.PRESET_COLORS @@ -21,13 +17,22 @@ openpyxl.xml.functions.tostring openpyxl.utils.dataframe # Fake getters -openpyxl\.descriptors\..*\.__get__ +openpyxl.descriptors.(base.)?Descriptor.__get__ +openpyxl.descriptors.(base.)?MatchPattern.__get__ +openpyxl.descriptors.(base.)?Typed.__get__ +openpyxl.descriptors.nested.EmptyTag.__get__ +openpyxl.descriptors.nested.Nested.__get__ +openpyxl.descriptors.nested.NestedMinMax.__get__ +openpyxl.descriptors.nested.NestedText.__get__ +openpyxl.descriptors.nested.NestedValue.__get__ # Stubtest sees and type[T] as different: https://github.com/python/mypy/issues/13316 openpyxl.chart.descriptors.NumberFormatDescriptor.expected_type openpyxl.chart.title.TitleDescriptor.expected_type openpyxl.drawing.colors.ColorChoiceDescriptor.expected_type +openpyxl.packaging.relationship.RelationshipList.expected_type openpyxl.styles.colors.ColorDescriptor.expected_type +openpyxl.styles.fills.StopList.expected_type # Stubtest doesn't like generics here openpyxl\.descriptors\.(base\.)?Bool\.allow_none @@ -126,24 +131,16 @@ openpyxl.pivot.cache.CacheHierarchy.__init__ openpyxl.pivot.cache.CacheSource.__init__ openpyxl.pivot.cache.CalculatedItem.__init__ openpyxl.pivot.cache.CalculatedMember.__init__ -openpyxl.pivot.cache.DiscretePr.__init__ -openpyxl.pivot.cache.FieldsUsage.__init__ openpyxl.pivot.cache.FieldUsage.__init__ openpyxl.pivot.cache.GroupLevel.__init__ -openpyxl.pivot.cache.GroupLevels.__init__ openpyxl.pivot.cache.GroupMember.__init__ -openpyxl.pivot.cache.GroupMembers.__init__ -openpyxl.pivot.cache.Groups.__init__ openpyxl.pivot.cache.LevelGroup.__init__ openpyxl.pivot.cache.MeasureGroup.__init__ openpyxl.pivot.cache.OLAPSet.__init__ -openpyxl.pivot.cache.OLAPSets.__init__ openpyxl.pivot.cache.PageItem.__init__ -openpyxl.pivot.cache.PCDKPI.__init__ openpyxl.pivot.cache.PCDSDTCEntries.__init__ openpyxl.pivot.cache.PivotDimension.__init__ openpyxl.pivot.cache.Query.__init__ -openpyxl.pivot.cache.QueryCache.__init__ openpyxl.pivot.cache.RangeSet.__init__ openpyxl.pivot.fields.Error.__init__ openpyxl.pivot.fields.Number.__init__ diff --git a/stubs/openpyxl/METADATA.toml b/stubs/openpyxl/METADATA.toml index f2743c5bf..eef134504 100644 --- a/stubs/openpyxl/METADATA.toml +++ b/stubs/openpyxl/METADATA.toml @@ -1,2 +1,2 @@ -version = "3.1.2" +version = "3.1.4" upstream_repository = "https://foss.heptapod.net/openpyxl/openpyxl" diff --git a/stubs/openpyxl/openpyxl/cell/rich_text.pyi b/stubs/openpyxl/openpyxl/cell/rich_text.pyi index a5168ddf6..7f098a1b8 100644 --- a/stubs/openpyxl/openpyxl/cell/rich_text.pyi +++ b/stubs/openpyxl/openpyxl/cell/rich_text.pyi @@ -5,6 +5,7 @@ from typing_extensions import Self from openpyxl.cell.text import InlineFont from openpyxl.descriptors import Strict, String, Typed from openpyxl.descriptors.serialisable import _ChildSerialisableTreeElement +from openpyxl.xml.functions import Element class TextBlock(Strict): font: Typed[InlineFont, Literal[False]] @@ -12,6 +13,7 @@ class TextBlock(Strict): def __init__(self, font: InlineFont, text: str) -> None: ... def __eq__(self, other: TextBlock) -> bool: ... # type: ignore[override] + def to_tree(self) -> Element: ... class CellRichText(list[str | TextBlock]): @overload @@ -24,3 +26,4 @@ class CellRichText(list[str | TextBlock]): def append(self, arg: str | TextBlock) -> None: ... def extend(self, arg: Iterable[str | TextBlock]) -> None: ... def as_list(self) -> list[str]: ... + def to_tree(self) -> Element: ... diff --git a/stubs/openpyxl/openpyxl/chart/trendline.pyi b/stubs/openpyxl/openpyxl/chart/trendline.pyi index 88b6fd46d..e76da34ef 100644 --- a/stubs/openpyxl/openpyxl/chart/trendline.pyi +++ b/stubs/openpyxl/openpyxl/chart/trendline.pyi @@ -10,8 +10,7 @@ from openpyxl.descriptors.base import Alias, String, Typed, _ConvertibleToBool from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import NestedBool, NestedFloat, NestedInteger, NestedSet from openpyxl.descriptors.serialisable import Serialisable - -from ..xml._functions_overloads import _HasTagAndGet +from openpyxl.xml._functions_overloads import _HasTagAndGet _TrendlineTrendlineType: TypeAlias = Literal["exp", "linear", "log", "movingAvg", "poly", "power"] diff --git a/stubs/openpyxl/openpyxl/descriptors/base.pyi b/stubs/openpyxl/openpyxl/descriptors/base.pyi index 0bd080428..e7f9515bf 100644 --- a/stubs/openpyxl/openpyxl/descriptors/base.pyi +++ b/stubs/openpyxl/openpyxl/descriptors/base.pyi @@ -12,7 +12,7 @@ from openpyxl.worksheet.cell_range import CellRange, MultiCellRange _T = TypeVar("_T") _P = TypeVar("_P", str, ReadableBuffer) -_N = TypeVar("_N", bound=bool) +_N = TypeVar("_N", bound=bool, default=Literal[False]) _L = TypeVar("_L", bound=Sized) _M = TypeVar("_M", int, float) diff --git a/stubs/openpyxl/openpyxl/descriptors/container.pyi b/stubs/openpyxl/openpyxl/descriptors/container.pyi new file mode 100644 index 000000000..52106f1e6 --- /dev/null +++ b/stubs/openpyxl/openpyxl/descriptors/container.pyi @@ -0,0 +1,18 @@ +from typing import TypeVar +from typing_extensions import Self + +from openpyxl.descriptors.serialisable import Serialisable +from openpyxl.xml.functions import Element + +_T = TypeVar("_T", bound=Serialisable) + +# Abstract base class. +class ElementList(list[_T]): + @property + def tagname(self) -> str: ... # abstract + @property + def expected_type(self) -> type[_T]: ... # abstract + @classmethod + def from_tree(cls, tree: Element) -> Self: ... + def to_tree(self) -> Element: ... + def append(self, value: _T) -> None: ... diff --git a/stubs/openpyxl/openpyxl/descriptors/sequence.pyi b/stubs/openpyxl/openpyxl/descriptors/sequence.pyi index 6a86831bf..246ab1164 100644 --- a/stubs/openpyxl/openpyxl/descriptors/sequence.pyi +++ b/stubs/openpyxl/openpyxl/descriptors/sequence.pyi @@ -11,6 +11,7 @@ from openpyxl.xml.functions import Element from .base import Alias, Descriptor _T = TypeVar("_T") +_ContainerT = TypeVar("_ContainerT") class _SupportsFromTree(Protocol): @classmethod @@ -19,22 +20,27 @@ class _SupportsFromTree(Protocol): class _SupportsToTree(Protocol): def to_tree(self) -> Element: ... -class Sequence(Descriptor[Incomplete]): - expected_type: type[Incomplete] - seq_types: tuple[type, ...] +# `_ContainerT` is the internal container type (which defaults to `list`), or +# `IndexedList` if unique is `True`. +class Sequence(Descriptor[_ContainerT]): + expected_type: type[Any] # expected type of the sequence elements + seq_types: tuple[type, ...] # allowed settable sequence types, defaults to `list`, `tuple` idx_base: int unique: bool - container: type - def __set__(self, instance: Serialisable | Strict, seq) -> None: ... + container: type # internal container type, defaults to `list` + # seq must be an instance of any of the declared `seq_types`. + def __set__(self, instance: Serialisable | Strict, seq: Any) -> None: ... def to_tree( self, tagname: str | None, obj: Iterable[object], namespace: str | None = None ) -> Generator[Element, None, None]: ... -class UniqueSequence(Sequence): - seq_types: tuple[type, ...] - container: type +# `_T` is the type of the elements in the sequence. +class UniqueSequence(Sequence[set[_T]]): + seq_types: tuple[type[list[_T]], type[tuple[_T, ...]], type[set[_T]]] + container: type[set[_T]] -class ValueSequence(Sequence): +# See `Sequence` for the meaning of `_ContainerT`. +class ValueSequence(Sequence[_ContainerT]): attribute: str def to_tree( self, tagname: str, obj: Iterable[object], namespace: str | None = None # type: ignore[override] @@ -43,7 +49,8 @@ class ValueSequence(Sequence): class _NestedSequenceToTreeObj(Sized, Iterable[_SupportsToTree], Protocol): ... -class NestedSequence(Sequence): +# See `Sequence` for the meaning of `_ContainerT`. +class NestedSequence(Sequence[_ContainerT]): count: bool expected_type: type[_SupportsFromTree] def to_tree( # type: ignore[override] @@ -53,8 +60,9 @@ class NestedSequence(Sequence): # Which can really be anything given the wildly different, and sometimes generic, from_tree return types def from_tree(self, node: Iterable[_SerialisableTreeElement]) -> list[Any]: ... -class MultiSequence(Sequence): - def __set__(self, instance: Serialisable | Strict, seq) -> None: ... +# `_T` is the type of the elements in the sequence. +class MultiSequence(Sequence[list[_T]]): + def __set__(self, instance: Serialisable | Strict, seq: tuple[_T, ...] | list[_T]) -> None: ... def to_tree( self, tagname: Unused, obj: Iterable[_SupportsToTree], namespace: str | None = None # type: ignore[override] ) -> Generator[Element, None, None]: ... diff --git a/stubs/openpyxl/openpyxl/packaging/custom.pyi b/stubs/openpyxl/openpyxl/packaging/custom.pyi index a01a5a098..ec95af53f 100644 --- a/stubs/openpyxl/openpyxl/packaging/custom.pyi +++ b/stubs/openpyxl/openpyxl/packaging/custom.pyi @@ -52,7 +52,7 @@ CLASS_MAPPING: Final[dict[type[_MappingPropertyType], str]] XML_MAPPING: Final[dict[str, type[_MappingPropertyType]]] class CustomPropertyList(Strict, Generic[_T]): - props: Sequence + props: Sequence[list[_TypedProperty[_T]]] def __init__(self) -> None: ... @classmethod def from_tree(cls, tree: _ChildSerialisableTreeElement) -> Self: ... diff --git a/stubs/openpyxl/openpyxl/packaging/extended.pyi b/stubs/openpyxl/openpyxl/packaging/extended.pyi index 9eedb949f..3a729711c 100644 --- a/stubs/openpyxl/openpyxl/packaging/extended.pyi +++ b/stubs/openpyxl/openpyxl/packaging/extended.pyi @@ -76,8 +76,8 @@ class ExtendedProperties(Serialisable): HLinks: Unused = None, HyperlinksChanged: object = None, DigSig: Unused = None, - Application: object = "Microsoft Excel", - AppVersion: object = None, + Application: Unused = None, + AppVersion: str | None = None, DocSecurity: ConvertibleToInt | None = None, ) -> None: ... def to_tree(self) -> Element: ... # type: ignore[override] diff --git a/stubs/openpyxl/openpyxl/packaging/relationship.pyi b/stubs/openpyxl/openpyxl/packaging/relationship.pyi index e0ddf4c8b..1a1ea10a1 100644 --- a/stubs/openpyxl/openpyxl/packaging/relationship.pyi +++ b/stubs/openpyxl/openpyxl/packaging/relationship.pyi @@ -4,11 +4,11 @@ from typing import ClassVar, Literal, TypeVar, overload from zipfile import ZipFile from openpyxl.descriptors.base import Alias, String +from openpyxl.descriptors.container import ElementList from openpyxl.descriptors.serialisable import Serialisable from openpyxl.pivot.cache import CacheDefinition from openpyxl.pivot.record import RecordList from openpyxl.pivot.table import TableDefinition -from openpyxl.xml.functions import Element _SerialisableT = TypeVar("_SerialisableT", bound=Serialisable) _SerialisableRelTypeT = TypeVar("_SerialisableRelTypeT", bound=CacheDefinition | RecordList | TableDefinition) @@ -32,16 +32,11 @@ class Relationship(Serialisable): self, Id: str, Type: str, type: None = None, Target: str | None = None, TargetMode: str | None = None ) -> None: ... -class RelationshipList(Serialisable): - tagname: ClassVar[str] - Relationship: Incomplete - def __init__(self, Relationship=()) -> None: ... - def append(self, value) -> None: ... - def __len__(self) -> int: ... - def __bool__(self) -> bool: ... - def find(self, content_type) -> Generator[Incomplete, None, None]: ... - def __getitem__(self, key): ... - def to_tree(self) -> Element: ... # type: ignore[override] +class RelationshipList(ElementList[Relationship]): + expected_type: type[Relationship] + def find(self, content_type: str) -> Generator[Relationship, None, None]: ... + def get(self, key: str) -> Relationship: ... + def to_dict(self) -> dict[Incomplete, Relationship]: ... def get_rels_path(path): ... def get_dependents(archive: ZipFile, filename: str) -> RelationshipList: ... diff --git a/stubs/openpyxl/openpyxl/pivot/cache.pyi b/stubs/openpyxl/openpyxl/pivot/cache.pyi index 5cb3571cd..bd8c5f6ca 100644 --- a/stubs/openpyxl/openpyxl/pivot/cache.pyi +++ b/stubs/openpyxl/openpyxl/pivot/cache.pyi @@ -3,9 +3,10 @@ from datetime import datetime from typing import ClassVar, Literal, overload from typing_extensions import TypeAlias -from openpyxl.descriptors.base import Bool, DateTime, Float, Integer, Set, String, Typed, _ConvertibleToBool +from openpyxl.descriptors.base import Bool, DateTime, Float, Integer, NoneSet, Set, String, Typed, _ConvertibleToBool from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.nested import NestedInteger +from openpyxl.descriptors.sequence import NestedSequence from openpyxl.descriptors.serialisable import Serialisable from openpyxl.pivot.fields import Error, Missing, Number, Text, TupleList from openpyxl.pivot.table import PivotArea @@ -43,10 +44,10 @@ class CalculatedMember(Serialisable): tagname: ClassVar[str] name: String[Literal[False]] mdx: String[Literal[False]] - memberName: String[Literal[False]] - hierarchy: String[Literal[False]] - parent: String[Literal[False]] - solveOrder: Integer[Literal[False]] + memberName: String[Literal[True]] + hierarchy: String[Literal[True]] + parent: String[Literal[True]] + solveOrder: Integer[Literal[True]] set: Bool[Literal[False]] extLst: Typed[ExtensionList, Literal[True]] __elements__: ClassVar[tuple[str, ...]] @@ -84,15 +85,6 @@ class ServerFormat(Serialisable): format: String[Literal[True]] def __init__(self, culture: str | None = None, format: str | None = None) -> None: ... -class ServerFormatList(Serialisable): - tagname: ClassVar[str] - serverFormat: Incomplete - __elements__: ClassVar[tuple[str, ...]] - __attrs__: ClassVar[tuple[str, ...]] - def __init__(self, count: Incomplete | None = None, serverFormat: Incomplete | None = None) -> None: ... - @property - def count(self) -> int: ... - class Query(Serialisable): tagname: ClassVar[str] mdx: String[Literal[False]] @@ -100,13 +92,6 @@ class Query(Serialisable): __elements__: ClassVar[tuple[str, ...]] def __init__(self, mdx: str, tpls: TupleList | None = None) -> None: ... -class QueryCache(Serialisable): - tagname: ClassVar[str] - count: Integer[Literal[False]] - query: Typed[Query, Literal[False]] - __elements__: ClassVar[tuple[str, ...]] - def __init__(self, count: ConvertibleToInt, query: Query) -> None: ... - class OLAPSet(Serialisable): tagname: ClassVar[str] count: Integer[Literal[False]] @@ -128,82 +113,59 @@ class OLAPSet(Serialisable): sortByTuple: TupleList | None = None, ) -> None: ... -class OLAPSets(Serialisable): - count: Integer[Literal[False]] - set: Typed[OLAPSet, Literal[False]] - __elements__: ClassVar[tuple[str, ...]] - def __init__(self, count: ConvertibleToInt, set: OLAPSet) -> None: ... - class PCDSDTCEntries(Serialisable): tagname: ClassVar[str] - count: Integer[Literal[False]] - m: Typed[Missing, Literal[False]] - n: Typed[Number, Literal[False]] - e: Typed[Error, Literal[False]] - s: Typed[Text, Literal[False]] + count: Integer[Literal[True]] + m: Typed[Missing, Literal[True]] + n: Typed[Number, Literal[True]] + e: Typed[Error, Literal[True]] + s: Typed[Text, Literal[True]] __elements__: ClassVar[tuple[str, ...]] def __init__(self, count: ConvertibleToInt, m: Missing, n: Number, e: Error, s: Text) -> None: ... class TupleCache(Serialisable): tagname: ClassVar[str] entries: Typed[PCDSDTCEntries, Literal[True]] - sets: Typed[OLAPSets, Literal[True]] - queryCache: Typed[QueryCache, Literal[True]] - serverFormats: Typed[ServerFormatList, Literal[True]] + sets: NestedSequence[list[OLAPSet]] + queryCache: NestedSequence[list[Query]] + serverFormats: NestedSequence[list[ServerFormat]] extLst: Typed[ExtensionList, Literal[True]] __elements__: ClassVar[tuple[str, ...]] def __init__( self, entries: PCDSDTCEntries | None = None, - sets: OLAPSets | None = None, - queryCache: QueryCache | None = None, - serverFormats: ServerFormatList | None = None, + sets: list[OLAPSet] | tuple[OLAPSet, ...] = (), + queryCache: list[Query] | tuple[Query, ...] = (), + serverFormats: list[ServerFormat] | tuple[ServerFormat, ...] = (), extLst: ExtensionList | None = None, ) -> None: ... -class PCDKPI(Serialisable): +class OLAPKPI(Serialisable): tagname: ClassVar[str] uniqueName: String[Literal[False]] caption: String[Literal[True]] - displayFolder: String[Literal[False]] - measureGroup: String[Literal[False]] - parent: String[Literal[False]] + displayFolder: String[Literal[True]] + measureGroup: String[Literal[True]] + parent: String[Literal[True]] value: String[Literal[False]] - goal: String[Literal[False]] - status: String[Literal[False]] - trend: String[Literal[False]] - weight: String[Literal[False]] - time: String[Literal[False]] - @overload + goal: String[Literal[True]] + status: String[Literal[True]] + trend: String[Literal[True]] + weight: String[Literal[True]] + time: String[Literal[True]] def __init__( self, - uniqueName: str, + uniqueName: str | None = None, caption: str | None = None, - *, - displayFolder: str, - measureGroup: str, - parent: str, - value: str, - goal: str, - status: str, - trend: str, - weight: str, - time: str, - ) -> None: ... - @overload - def __init__( - self, - uniqueName: str, - caption: str | None, - displayFolder: str, - measureGroup: str, - parent: str, - value: str, - goal: str, - status: str, - trend: str, - weight: str, - time: str, + displayFolder: str | None = None, + measureGroup: str | None = None, + parent: str | None = None, + value: str | None = None, + goal: str | None = None, + status: str | None = None, + trend: str | None = None, + weight: str | None = None, + time: str | None = None, ) -> None: ... class GroupMember(Serialisable): @@ -212,12 +174,6 @@ class GroupMember(Serialisable): group: Bool[Literal[False]] def __init__(self, uniqueName: str, group: _ConvertibleToBool = None) -> None: ... -class GroupMembers(Serialisable): - count: Integer[Literal[False]] - groupMember: Typed[GroupMember, Literal[False]] - __elements__: ClassVar[tuple[str, ...]] - def __init__(self, count: ConvertibleToInt, groupMember: GroupMember) -> None: ... - class LevelGroup(Serialisable): tagname: ClassVar[str] name: String[Literal[False]] @@ -225,26 +181,25 @@ class LevelGroup(Serialisable): caption: String[Literal[False]] uniqueParent: String[Literal[False]] id: Integer[Literal[False]] - groupMembers: Typed[GroupMembers, Literal[False]] + groupMembers: NestedSequence[list[GroupMember]] __elements__: ClassVar[tuple[str, ...]] def __init__( - self, name: str, uniqueName: str, caption: str, uniqueParent: str, id: ConvertibleToInt, groupMembers: GroupMembers + self, + name: str, + uniqueName: str, + caption: str, + uniqueParent: str, + id: ConvertibleToInt, + groupMembers: list[GroupMember] | tuple[GroupMember, ...] = (), ) -> None: ... -class Groups(Serialisable): - tagname: ClassVar[str] - count: Integer[Literal[False]] - group: Typed[LevelGroup, Literal[False]] - __elements__: ClassVar[tuple[str, ...]] - def __init__(self, count: ConvertibleToInt, group: LevelGroup) -> None: ... - class GroupLevel(Serialisable): tagname: ClassVar[str] uniqueName: String[Literal[False]] caption: String[Literal[False]] user: Bool[Literal[False]] customRollUp: Bool[Literal[False]] - groups: Typed[Groups, Literal[True]] + groups: NestedSequence[list[LevelGroup]] extLst: Typed[ExtensionList, Literal[True]] __elements__: ClassVar[tuple[str, ...]] def __init__( @@ -253,27 +208,15 @@ class GroupLevel(Serialisable): caption: str, user: _ConvertibleToBool = None, customRollUp: _ConvertibleToBool = None, - groups: Groups | None = None, + groups: list[LevelGroup] | tuple[LevelGroup, ...] = (), extLst: ExtensionList | None = None, ) -> None: ... -class GroupLevels(Serialisable): - count: Integer[Literal[False]] - groupLevel: Typed[GroupLevel, Literal[False]] - __elements__: ClassVar[tuple[str, ...]] - def __init__(self, count: ConvertibleToInt, groupLevel: GroupLevel) -> None: ... - class FieldUsage(Serialisable): tagname: ClassVar[str] x: Integer[Literal[False]] def __init__(self, x: ConvertibleToInt) -> None: ... -class FieldsUsage(Serialisable): - count: Integer[Literal[False]] - fieldUsage: Typed[FieldUsage, Literal[True]] - __elements__: ClassVar[tuple[str, ...]] - def __init__(self, count: ConvertibleToInt, fieldUsage: FieldUsage | None = None) -> None: ... - class CacheHierarchy(Serialisable): tagname: ClassVar[str] uniqueName: String[Literal[False]] @@ -298,8 +241,8 @@ class CacheHierarchy(Serialisable): unbalanced: Bool[Literal[True]] unbalancedGroup: Bool[Literal[True]] hidden: Bool[Literal[False]] - fieldsUsage: Typed[FieldsUsage, Literal[True]] - groupLevels: Typed[GroupLevels, Literal[True]] + fieldsUsage: NestedSequence[list[FieldUsage]] + groupLevels: NestedSequence[list[GroupLevel]] extLst: Typed[ExtensionList, Literal[True]] __elements__: ClassVar[tuple[str, ...]] @overload @@ -328,8 +271,8 @@ class CacheHierarchy(Serialisable): unbalanced: _ConvertibleToBool | None = None, unbalancedGroup: _ConvertibleToBool | None = None, hidden: _ConvertibleToBool = None, - fieldsUsage: FieldsUsage | None = None, - groupLevels: GroupLevels | None = None, + fieldsUsage: list[FieldUsage] | tuple[FieldUsage, ...] = (), + groupLevels: list[FieldUsage] | tuple[FieldUsage, ...] = (), extLst: ExtensionList | None = None, ) -> None: ... @overload @@ -357,8 +300,8 @@ class CacheHierarchy(Serialisable): unbalanced: _ConvertibleToBool | None = None, unbalancedGroup: _ConvertibleToBool | None = None, hidden: _ConvertibleToBool = None, - fieldsUsage: FieldsUsage | None = None, - groupLevels: GroupLevels | None = None, + fieldsUsage: list[FieldUsage] | tuple[FieldUsage, ...] = (), + groupLevels: list[FieldUsage] | tuple[FieldUsage, ...] = (), extLst: ExtensionList | None = None, ) -> None: ... @@ -376,20 +319,11 @@ class GroupItems(Serialisable): @property def count(self) -> int: ... -class DiscretePr(Serialisable): - tagname: ClassVar[str] - count: Integer[Literal[False]] - x: NestedInteger[Literal[True]] - __elements__: ClassVar[tuple[str, ...]] - def __init__( - self, count: ConvertibleToInt, x: _HasTagAndGet[ConvertibleToInt | None] | ConvertibleToInt | None = None - ) -> None: ... - class RangePr(Serialisable): tagname: ClassVar[str] autoStart: Bool[Literal[True]] autoEnd: Bool[Literal[True]] - groupBy: Set[_RangePrGroupBy] + groupBy: NoneSet[_RangePrGroupBy] startNum: Float[Literal[True]] endNum: Float[Literal[True]] startDate: DateTime[Literal[True]] @@ -412,7 +346,7 @@ class FieldGroup(Serialisable): par: Integer[Literal[True]] base: Integer[Literal[True]] rangePr: Typed[RangePr, Literal[True]] - discretePr: Typed[DiscretePr, Literal[True]] + discretePr: NestedSequence[list[NestedInteger[Literal[False]]]] groupItems: Typed[GroupItems, Literal[True]] __elements__: ClassVar[tuple[str, ...]] def __init__( @@ -420,7 +354,7 @@ class FieldGroup(Serialisable): par: ConvertibleToInt | None = None, base: ConvertibleToInt | None = None, rangePr: RangePr | None = None, - discretePr: DiscretePr | None = None, + discretePr: list[NestedInteger[Literal[False]]] | tuple[NestedInteger[Literal[False]], ...] = (), groupItems: GroupItems | None = None, ) -> None: ... @@ -569,21 +503,18 @@ class PageItem(Serialisable): name: String[Literal[False]] def __init__(self, name: str) -> None: ... -class Page(Serialisable): - tagname: ClassVar[str] - pageItem: Incomplete - __elements__: ClassVar[tuple[str, ...]] - def __init__(self, count: Incomplete | None = None, pageItem: Incomplete | None = None) -> None: ... - @property - def count(self) -> int: ... - class Consolidation(Serialisable): tagname: ClassVar[str] autoPage: Bool[Literal[True]] - pages: Incomplete - rangeSets: Incomplete + pages: NestedSequence[list[PageItem]] + rangeSets: NestedSequence[list[RangeSet]] __elements__: ClassVar[tuple[str, ...]] - def __init__(self, autoPage: _ConvertibleToBool | None = None, pages=(), rangeSets=()) -> None: ... + def __init__( + self, + autoPage: _ConvertibleToBool | None = None, + pages: list[PageItem] | tuple[PageItem, ...] = (), + rangeSets: list[RangeSet] | tuple[RangeSet, ...] = (), + ) -> None: ... class WorksheetSource(Serialisable): tagname: ClassVar[str] @@ -629,13 +560,13 @@ class CacheDefinition(Serialisable): minRefreshableVersion: Integer[Literal[True]] recordCount: Integer[Literal[True]] upgradeOnRefresh: Bool[Literal[True]] - tupleCache: Typed[TupleCache, Literal[True]] supportSubquery: Bool[Literal[True]] supportAdvancedDrill: Bool[Literal[True]] cacheSource: Typed[CacheSource, Literal[True]] cacheFields: Incomplete cacheHierarchies: Incomplete - kpis: Incomplete + kpis: NestedSequence[list[OLAPKPI]] + tupleCache: Typed[TupleCache, Literal[True]] calculatedItems: Incomplete calculatedMembers: Incomplete dimensions: Incomplete @@ -669,7 +600,7 @@ class CacheDefinition(Serialisable): cacheSource: CacheSource, cacheFields=(), cacheHierarchies=(), - kpis=(), + kpis: list[OLAPKPI] | tuple[OLAPKPI, ...] = (), calculatedItems=(), calculatedMembers=(), dimensions=(), diff --git a/stubs/openpyxl/openpyxl/pivot/fields.pyi b/stubs/openpyxl/openpyxl/pivot/fields.pyi index 3076fed4a..a35b43114 100644 --- a/stubs/openpyxl/openpyxl/pivot/fields.pyi +++ b/stubs/openpyxl/openpyxl/pivot/fields.pyi @@ -11,8 +11,8 @@ class Index(Serialisable): def __init__(self, v: ConvertibleToInt | None = 0) -> None: ... class Tuple(Serialisable): - fld: Integer[Literal[False]] - hier: Integer[Literal[False]] + fld: Integer[Literal[True]] + hier: Integer[Literal[True]] item: Integer[Literal[False]] def __init__(self, fld: ConvertibleToInt, hier: ConvertibleToInt, item: ConvertibleToInt) -> None: ... diff --git a/stubs/openpyxl/openpyxl/styles/alignment.pyi b/stubs/openpyxl/openpyxl/styles/alignment.pyi index d2b96de0a..6bad3b071 100644 --- a/stubs/openpyxl/openpyxl/styles/alignment.pyi +++ b/stubs/openpyxl/openpyxl/styles/alignment.pyi @@ -16,7 +16,6 @@ vertical_aligments: Final[tuple[_VerticalAlignmentsType, ...]] class Alignment(Serialisable): tagname: ClassVar[str] - __fields__: ClassVar[tuple[str, ...]] horizontal: NoneSet[_HorizontalAlignmentsType] vertical: NoneSet[_VerticalAlignmentsType] textRotation: NoneSet[int] diff --git a/stubs/openpyxl/openpyxl/styles/borders.pyi b/stubs/openpyxl/openpyxl/styles/borders.pyi index 5c05d5666..c54e2e55d 100644 --- a/stubs/openpyxl/openpyxl/styles/borders.pyi +++ b/stubs/openpyxl/openpyxl/styles/borders.pyi @@ -39,7 +39,6 @@ BORDER_THICK: Final = "thick" BORDER_THIN: Final = "thin" class Side(Serialisable): - __fields__: ClassVar[tuple[str, ...]] color: ColorDescriptor[Literal[True]] style: NoneSet[_SideStyle] border_style: Alias @@ -52,7 +51,6 @@ class Side(Serialisable): class Border(Serialisable): tagname: ClassVar[str] - __fields__: ClassVar[tuple[str, ...]] __elements__: ClassVar[tuple[str, ...]] start: Typed[Side, Literal[True]] end: Typed[Side, Literal[True]] diff --git a/stubs/openpyxl/openpyxl/styles/fills.pyi b/stubs/openpyxl/openpyxl/styles/fills.pyi index 7e1a62a98..85be254a9 100644 --- a/stubs/openpyxl/openpyxl/styles/fills.pyi +++ b/stubs/openpyxl/openpyxl/styles/fills.pyi @@ -88,9 +88,9 @@ class Stop(Serialisable): color: Incomplete def __init__(self, color, position: ConvertibleToFloat) -> None: ... -class StopList(Sequence): - expected_type: type[Incomplete] - def __set__(self, obj: Serialisable | Strict, values) -> None: ... +class StopList(Sequence[list[Stop]]): + expected_type: type[Stop] + def __set__(self, obj: Serialisable | Strict, values: list[Stop] | tuple[Stop, ...]) -> None: ... class GradientFill(Fill): tagname: ClassVar[str] diff --git a/stubs/openpyxl/openpyxl/styles/named_styles.pyi b/stubs/openpyxl/openpyxl/styles/named_styles.pyi index 2cb2b2451..2e598cdb3 100644 --- a/stubs/openpyxl/openpyxl/styles/named_styles.pyi +++ b/stubs/openpyxl/openpyxl/styles/named_styles.pyi @@ -4,6 +4,7 @@ from typing import ClassVar, Literal from openpyxl.descriptors.base import Bool, Integer, String, Typed, _ConvertibleToBool from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.sequence import Sequence from openpyxl.descriptors.serialisable import Serialisable from openpyxl.styles.alignment import Alignment from openpyxl.styles.borders import Border @@ -22,8 +23,6 @@ class NamedStyle(Serialisable): protection: Typed[Protection, Literal[False]] builtinId: Integer[Literal[True]] hidden: Bool[Literal[True]] - # Overwritten by property below - # xfId: Integer name: String[Literal[False]] def __init__( self, @@ -36,12 +35,9 @@ class NamedStyle(Serialisable): protection: Protection | None = None, builtinId: ConvertibleToInt | None = None, hidden: _ConvertibleToBool | None = False, - xfId: Unused = None, ) -> None: ... def __setattr__(self, attr: str, value) -> None: ... def __iter__(self) -> Iterator[tuple[str, str]]: ... - @property - def xfId(self) -> int | None: ... def bind(self, wb: Workbook) -> None: ... def as_tuple(self) -> StyleArray: ... def as_xf(self) -> CellStyle: ... @@ -77,11 +73,10 @@ class _NamedCellStyle(Serialisable): class _NamedCellStyleList(Serialisable): tagname: ClassVar[str] # Overwritten by property below - # count: Integer - cellStyle: Incomplete + # count: Integer[Literal[True]] + cellStyle: Sequence[list[_NamedCellStyle]] __attrs__: ClassVar[tuple[str, ...]] - def __init__(self, count: Unused = None, cellStyle=()) -> None: ... + def __init__(self, count: Unused = None, cellStyle: list[_NamedCellStyle] | tuple[_NamedCellStyle, ...] = ()) -> None: ... @property def count(self) -> int: ... - @property - def names(self) -> NamedStyleList: ... + def remove_duplicates(self) -> list[_NamedCellStyle]: ... diff --git a/stubs/openpyxl/openpyxl/utils/cell.pyi b/stubs/openpyxl/openpyxl/utils/cell.pyi index 1d3b0b8e2..22a05774e 100644 --- a/stubs/openpyxl/openpyxl/utils/cell.pyi +++ b/stubs/openpyxl/openpyxl/utils/cell.pyi @@ -17,8 +17,8 @@ SHEETRANGE_RE: Final[Pattern[str]] def get_column_interval(start: str | int, end: str | int) -> list[str]: ... def coordinate_from_string(coord_string: str) -> tuple[str, int]: ... def absolute_coordinate(coord_string: str) -> str: ... -def get_column_letter(idx: int) -> str: ... -def column_index_from_string(str_col: str) -> int: ... +def get_column_letter(col_idx: int) -> str: ... +def column_index_from_string(col: str) -> int: ... def range_boundaries(range_string: str) -> _RangeBoundariesTuple: ... def rows_from_range(range_string: str) -> Generator[tuple[str, ...], None, None]: ... def cols_from_range(range_string: str) -> Generator[tuple[str, ...], None, None]: ... diff --git a/stubs/openpyxl/openpyxl/utils/indexed_list.pyi b/stubs/openpyxl/openpyxl/utils/indexed_list.pyi index 417198076..9bf453a04 100644 --- a/stubs/openpyxl/openpyxl/utils/indexed_list.pyi +++ b/stubs/openpyxl/openpyxl/utils/indexed_list.pyi @@ -7,6 +7,6 @@ class IndexedList(list[_T]): clean: bool def __init__(self, iterable: Iterable[_T] | None = None) -> None: ... def __contains__(self, value: object) -> bool: ... - def index(self, value: _T): ... # type: ignore[override] + def index(self, value: _T) -> int: ... # type: ignore[override] def append(self, value: _T) -> None: ... - def add(self, value: _T): ... + def add(self, value: _T) -> int: ... diff --git a/stubs/openpyxl/openpyxl/workbook/defined_name.pyi b/stubs/openpyxl/openpyxl/workbook/defined_name.pyi index 0e7393ccf..4c456d189 100644 --- a/stubs/openpyxl/openpyxl/workbook/defined_name.pyi +++ b/stubs/openpyxl/openpyxl/workbook/defined_name.pyi @@ -65,7 +65,7 @@ class DefinedNameDict(dict[str, DefinedName]): class DefinedNameList(Serialisable): tagname: ClassVar[str] - definedName: Sequence - def __init__(self, definedName=()) -> None: ... + definedName: Sequence[list[DefinedName]] + def __init__(self, definedName: list[DefinedName] | tuple[DefinedName, ...] = ()) -> None: ... def by_sheet(self) -> defaultdict[int, DefinedNameDict]: ... def __len__(self) -> int: ... diff --git a/stubs/openpyxl/openpyxl/worksheet/datavalidation.pyi b/stubs/openpyxl/openpyxl/worksheet/datavalidation.pyi index cd44c40a1..85f40baea 100644 --- a/stubs/openpyxl/openpyxl/worksheet/datavalidation.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/datavalidation.pyi @@ -72,7 +72,7 @@ class DataValidation(Serialisable): showErrorMessage: _ConvertibleToBool | None = False, showInputMessage: _ConvertibleToBool | None = False, showDropDown: _ConvertibleToBool | None = False, - allowBlank: _ConvertibleToBool | None = False, + allowBlank: _ConvertibleToBool = False, sqref: _ConvertibleToMultiCellRange = (), promptTitle: str | None = None, errorStyle: _DataValidationErrorStyle | Literal["none"] | None = None, @@ -81,7 +81,7 @@ class DataValidation(Serialisable): errorTitle: str | None = None, imeMode: _DataValidationImeMode | Literal["none"] | None = None, operator: _DataValidationOperator | Literal["none"] | None = None, - allow_blank: Incomplete | None = False, + allow_blank: _ConvertibleToBool | None = None, ) -> None: ... def add(self, cell) -> None: ... def __contains__(self, cell: _HasCoordinate | str | CellRange) -> bool: ... diff --git a/stubs/openpyxl/openpyxl/worksheet/dimensions.pyi b/stubs/openpyxl/openpyxl/worksheet/dimensions.pyi index 6a338deeb..03a849348 100644 --- a/stubs/openpyxl/openpyxl/worksheet/dimensions.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/dimensions.pyi @@ -102,6 +102,8 @@ class ColumnDimension(Dimension): @property def customWidth(self) -> bool: ... def reindex(self) -> None: ... + @property + def range(self) -> str: ... def to_tree(self) -> Element | None: ... class DimensionHolder(BoundDictionary[_DimKeyT, _DimT]): diff --git a/stubs/openpyxl/openpyxl/worksheet/filters.pyi b/stubs/openpyxl/openpyxl/worksheet/filters.pyi index 30d12af81..4a641e818 100644 --- a/stubs/openpyxl/openpyxl/worksheet/filters.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/filters.pyi @@ -1,14 +1,11 @@ from _typeshed import ConvertibleToFloat, ConvertibleToInt, Incomplete, Unused from datetime import datetime -from re import Pattern -from typing import ClassVar, Literal, overload +from typing import ClassVar, Final, Literal, overload from typing_extensions import TypeAlias -from openpyxl.descriptors import Strict from openpyxl.descriptors.base import ( Alias, Bool, - Convertible, DateTime, Float, Integer, @@ -22,8 +19,6 @@ from openpyxl.descriptors.base import ( from openpyxl.descriptors.excel import ExtensionList from openpyxl.descriptors.serialisable import Serialisable -from ..descriptors.base import _N - _SortConditionSortBy: TypeAlias = Literal["value", "cellColor", "fontColor", "icon"] _IconSet: TypeAlias = Literal[ "3Arrows", @@ -48,6 +43,7 @@ _SortStateSortMethod: TypeAlias = Literal["stroke", "pinYin"] _CustomFilterOperator: TypeAlias = Literal[ "equal", "lessThan", "lessThanOrEqual", "notEqual", "greaterThanOrEqual", "greaterThan" ] +_StringFilterOperator: TypeAlias = Literal["contains", "startswith", "endswith", "wildcard"] _FiltersCalendarType: TypeAlias = Literal[ "gregorian", "gregorianUs", @@ -170,24 +166,32 @@ class DynamicFilter(Serialisable): maxValIso: datetime | str | None = None, ) -> None: ... -class CustomFilterValueDescriptor(Convertible[float | str, _N]): - pattern: Pattern[str] - expected_type: type[float | str] - @overload # type: ignore[override] # Different restrictions - def __set__( - self: CustomFilterValueDescriptor[Literal[True]], instance: Serialisable | Strict, value: str | ConvertibleToFloat | None - ) -> None: ... - @overload - def __set__( - self: CustomFilterValueDescriptor[Literal[False]], instance: Serialisable | Strict, value: str | ConvertibleToFloat - ) -> None: ... - class CustomFilter(Serialisable): tagname: ClassVar[str] - operator: NoneSet[_CustomFilterOperator] - val: Incomplete + val: String[Literal[False]] + operator: Set[_CustomFilterOperator] + def __init__(self, operator: _CustomFilterOperator = "equal", val: str | None = None) -> None: ... + def convert(self) -> BlankFilter | NumberFilter | StringFilter: ... + +class BlankFilter(CustomFilter): + def __init__(self, **kw: Unused) -> None: ... + @property + def operator(self) -> Literal["notEqual"]: ... # type: ignore[override] + @property + def val(self) -> Literal[" "]: ... # type: ignore[override] + +class NumberFilter(CustomFilter): + val: Float[Literal[False]] # type: ignore[assignment] + def __init__(self, operator: _CustomFilterOperator = "equal", val: ConvertibleToFloat | None = None) -> None: ... + +string_format_mapping: Final[dict[_StringFilterOperator, str]] + +class StringFilter(CustomFilter): + operator: Set[_StringFilterOperator] # type: ignore[assignment] + val: String[Literal[False]] + exclude: Bool[Literal[False]] def __init__( - self, operator: _CustomFilterOperator | Literal["none"] | None = None, val: Incomplete | None = None + self, operator: _StringFilterOperator = "contains", val: str | None = None, exclude: _ConvertibleToBool = False ) -> None: ... class CustomFilters(Serialisable): @@ -195,7 +199,7 @@ class CustomFilters(Serialisable): _and: Bool[Literal[True]] # Not private. Avoids name clash customFilter: Incomplete __elements__: ClassVar[tuple[str, ...]] - def __init__(self, _and: _ConvertibleToBool | None = False, customFilter=()) -> None: ... + def __init__(self, _and: _ConvertibleToBool | None = None, customFilter=()) -> None: ... class Top10(Serialisable): tagname: ClassVar[str] diff --git a/stubs/openpyxl/openpyxl/worksheet/hyperlink.pyi b/stubs/openpyxl/openpyxl/worksheet/hyperlink.pyi index 03fa57ea7..1e8c5e166 100644 --- a/stubs/openpyxl/openpyxl/worksheet/hyperlink.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/hyperlink.pyi @@ -2,6 +2,7 @@ from _typeshed import Incomplete from typing import ClassVar, Literal from openpyxl.descriptors.base import String +from openpyxl.descriptors.sequence import Sequence from openpyxl.descriptors.serialisable import Serialisable class Hyperlink(Serialisable): @@ -25,8 +26,5 @@ class Hyperlink(Serialisable): class HyperlinkList(Serialisable): tagname: ClassVar[str] - hyperlink: Incomplete - def __init__(self, hyperlink=()) -> None: ... - def __bool__(self) -> bool: ... - def __len__(self) -> int: ... - def append(self, value) -> None: ... + hyperlink: Sequence[list[Hyperlink]] + def __init__(self, hyperlink: list[Hyperlink] | tuple[Hyperlink, ...] = ()) -> None: ... diff --git a/stubs/openpyxl/openpyxl/worksheet/views.pyi b/stubs/openpyxl/openpyxl/worksheet/views.pyi index 0663b9ea4..6ea3c2acf 100644 --- a/stubs/openpyxl/openpyxl/worksheet/views.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/views.pyi @@ -4,6 +4,7 @@ from typing_extensions import TypeAlias from openpyxl.descriptors.base import Bool, Float, Integer, NoneSet, Set, String, Typed, _ConvertibleToBool from openpyxl.descriptors.excel import ExtensionList +from openpyxl.descriptors.sequence import Sequence from openpyxl.descriptors.serialisable import Serialisable _Pane: TypeAlias = Literal["bottomRight", "topRight", "bottomLeft", "topLeft"] @@ -90,7 +91,9 @@ class SheetView(Serialisable): class SheetViewList(Serialisable): tagname: ClassVar[str] - sheetView: Incomplete + sheetView: Sequence[list[SheetView]] extLst: Typed[ExtensionList, Literal[True]] __elements__: ClassVar[tuple[str, ...]] - def __init__(self, sheetView: Incomplete | None = None, extLst: Unused = None) -> None: ... + def __init__(self, sheetView: SheetView | None = None, extLst: Unused = None) -> None: ... + @property + def active(self) -> SheetView: ... diff --git a/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi b/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi index f1930d010..436b4a114 100644 --- a/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi +++ b/stubs/openpyxl/openpyxl/worksheet/worksheet.pyi @@ -190,6 +190,8 @@ class Worksheet(_WorkbookChild): ) -> Generator[tuple[Cell, ...], None, None] | Generator[tuple[str | float | datetime | None, ...], None, None]: ... @property def columns(self) -> Generator[tuple[Cell, ...], None, None]: ... + @property + def column_groups(self) -> list[str]: ... def set_printer_settings( self, paper_size: int | None, orientation: Literal["default", "portrait", "landscape"] | None ) -> None: ...