Skip to content

Openpyxl typeshed errors #9836

Closed as not planned
Closed as not planned

Description

@tritemio

In an internal project, updating to 3.0.4.7 causes mypy in strict mode to generate the following error:

ocra.py:120: error: Value of type "_WorkbookChild" is not indexable  [index]
ocra.py:124: error: "_WorkbookChild" has no attribute "iter_rows"  [attr-defined]

The code for line 120 is:

...
wb = openpyxl.load_workbook(path)
ws = wb.active
header = [cell.value for cell in ws[1]]  # line 120
...

and for line 124:

ws.iter_rows(min_row=2)  # line 124

The same code checked using 3.0.4.6 passes all mypy checks in strick mode.

It seems like #9764 introduced a regression?

Activity

  1. srittau commented on Mar 6, 2023

    @srittau
    Collaborator

    #9764 actually made load_workbook() return a Workbook. Previously, it returned Any. The problem is that wb.active can return other workbook children (and even None), not only Worksheets. The easiest way to work around this problem is to use:

    wb = openpyxl.load_workbook(path)
    ws = wb.active
    assert isinstance(ws, Worksheet)
    header = [cell.value for cell in ws[1]]  # line 120

    Cc @mynhardtburger

  2. Avasam commented on Mar 7, 2023

    @Avasam
    SponsorCollaborator

    +1 what @srittau said.
    Even in #9511 I made load_workbook return a Workbook, the type comes from: https://foss.heptapod.net/openpyxl/openpyxl/-/blob/branch/3.1/openpyxl/reader/workbook.py#L31

  3. tritemio commented on Mar 8, 2023

    @tritemio
    Author

    Thanks for the quick answer. I'll apply the workaround to fix the code.

    Maybe it could a good idea to write in the changelog that the type stubs are now more accurate and this may require changes to existing code bases that implicitly relied on wb.active to be Any. A link to the fix in this thread could also be useful.

  4. srittau commented on Mar 8, 2023

    @srittau
    Collaborator

    @tritemio Unfortunately, our changelogs are currently auto-generated from git commit messages, which is why they are a bit messy and we can't edit them retroactively.

  5. AlbertoPuritano commented on Mar 9, 2023

    @AlbertoPuritano

    #9764 actually made load_workbook() return a Workbook. Previously, it returned Any. The problem is that wb.active can return other workbook children (and even None), not only Worksheets. The easiest way to work around this problem is to use:

    wb = openpyxl.load_workbook(path)
    ws = wb.active
    assert isinstance(ws, Worksheet)
    header = [cell.value for cell in ws[1]]  # line 120

    Cc @mynhardtburger

    Hello, apparently using the assert doesn't prevent mypy from reporting the error.. type hinting doesn't do much either, do you have any other solutions?

  6. srittau commented on Jun 12, 2023

    @srittau
    Collaborator

    I think the problems with wb.active have been explained. There isn't a better solution at the moment, until something like python/typing#566 becomes available.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions