Skip to content

Additional type hints added to stub openpyxl#9764

Merged
AlexWaygood merged 11 commits intopython:mainfrom
mynhardtburger:main
Feb 21, 2023
Merged

Additional type hints added to stub openpyxl#9764
AlexWaygood merged 11 commits intopython:mainfrom
mynhardtburger:main

Conversation

@mynhardtburger
Copy link
Copy Markdown
Contributor

@mynhardtburger mynhardtburger commented Feb 19, 2023

This is a continuation of the #9487 stale PR, with the recommended changes implemented.

@mynhardtburger
Copy link
Copy Markdown
Contributor Author

@Avasam FYI

Comment thread stubs/openpyxl/openpyxl/worksheet/worksheet.pyi Outdated
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much! This looks pretty good now -- here's a few comments from comparing this to the source code

Comment thread stubs/openpyxl/openpyxl/workbook/workbook.pyi Outdated
Comment thread stubs/openpyxl/openpyxl/workbook/workbook.pyi Outdated
Comment thread stubs/openpyxl/openpyxl/worksheet/worksheet.pyi Outdated
Comment thread stubs/openpyxl/openpyxl/worksheet/worksheet.pyi Outdated
Comment thread stubs/openpyxl/openpyxl/worksheet/worksheet.pyi Outdated
Comment thread stubs/openpyxl/openpyxl/worksheet/worksheet.pyi Outdated
Comment thread stubs/openpyxl/openpyxl/worksheet/worksheet.pyi Outdated
Comment thread stubs/openpyxl/openpyxl/worksheet/worksheet.pyi Outdated
@github-actions

This comment has been minimized.

Comment thread stubs/openpyxl/openpyxl/reader/excel.pyi Outdated
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one last point, then we're good to go!

def get_named_range(self, name): ...
def remove_named_range(self, named_range) -> None: ...
def named_styles(self) -> list[str]: ...
def get_named_ranges(self) -> list[DefinedName] | tuple[DefinedName]: ...
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def get_named_ranges(self) -> list[DefinedName] | tuple[DefinedName]: ...
def get_named_ranges(self) -> list[DefinedName] | tuple[DefinedName, ...]: ...

Remember that tuple[T] means "a single-element tuple where the sole element is of type T". You want tuple[T, ...] if you want to signify "a tuple of arbitrary length, where all elements are of type T".

We could also possibly simplify this by just doing Sequence[DefinedName] (with Sequence imported from collections.abc)?

Suggested change
def get_named_ranges(self) -> list[DefinedName] | tuple[DefinedName]: ...
def get_named_ranges(self) -> Sequence[DefinedName]: ...

Copy link
Copy Markdown
Contributor Author

@mynhardtburger mynhardtburger Feb 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on the tuple[DefinedName, ...].

collections.abc.Sequence is broader than just list and tuple. It also includes str and bytes: https://docs.python.org/3/glossary.html#term-sequence

I don't think collections.abc.Sequence would be appropriate.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collections.abc.Sequence is broader than just list and tuple. It also includes str and bytes: https://docs.python.org/3/glossary.html#term-sequence

str and bytes are indeed both sequences, correct — but neither is a subtype of Sequence[DefinedName]. str is a subtype of Sequence[str], and bytes is a subtype of Sequence[int]. So if I were writing this PR, I would favour the simpler approach here :)

But your approach isn't wrong by any means, and I don't want to be too picky :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 things here I just noticed (sorry it's been a while that I've looked at openpyxl)
1: descriptors are not meant to be used directly for type hints. Descriptors are assigned to ClassVars of classes subtyping Serializable. Serializable members act as properties where the setter uses the descriptor for runtime vlaidation of the setter
2. Whilst the Sequence descriptor allows both list and tuple (https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/3.1/openpyxl/descriptors/sequence.py#L18), DefinedNameList.definedName specifically needs to be sliceable and appendable (at least in 3.0, this doesn't seem to be the case anymore for 3.1) https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/3.0/openpyxl/workbook/defined_name.py#L207-209, the latter meaning it can't be a tuple.

@github-actions

This comment has been minimized.

@github-actions
Copy link
Copy Markdown
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

Copy link
Copy Markdown
Member

@AlexWaygood AlexWaygood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ArnabRollin for the initial PR, and thanks @mynhardtburger for finishing it! 🥳

@AlexWaygood AlexWaygood merged commit 3f6f54e into python:main Feb 21, 2023
@property
def columns(self) -> Generator[Cell, None, None]: ...
def set_printer_settings(
self, paper_size: int | None, orientation: None | Literal["default", "portrait", "landscape"]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another case for PyCQA/flake8-pyi#175 and PyCQA/flake8-pyi#283 -like checks in Flake8-PYI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants