Jakob Lovern
Jakob Lovern

Reputation: 1341

openpyxl: Linter insists that cell is merged

So I've got an excerpt from one of my classes:

def write_wb(self,filename: str):
    """Write the workbook to filename. """
    #This lets us defer excel ops until the end
    headers = ["Path","File","Type","Description","Link"]
    wb = openpyxl.Workbook()
    wb.active.append(headers)
    for elem in self._internal_array:
        wb.active.append([elem.path,
                          elem.name,
                          elem.type.name,
                          ''])
        linkcell = wb.active.cell(row=wb.active.max_row,column=5)
        linkcell.value = "1" #This line has the error
        linkcell.style = "Hyperlink"
        linkcell.font  = Font(underline="single")

My linter (pylance) keeps complaining of the following:

Cannot assign member "value" for type "MergedCell" Expression of type "Literal['1']" cannot be assigned to member "value" of class "MergedCell" Type cannot be assigned to type

Given that I created the workbook in line 5, I can make a compile-time guarantee that that cell will never be a MergedCell or a ReadOnlyCell. What's going on and how do I make my linter happy?

Upvotes: 1

Views: 114

Answers (1)

Jakob Lovern
Jakob Lovern

Reputation: 1341

The trick is to include your customized cell in the call to append. This code works:

for elem in self._internal_array:
    linkcell = openpyxl.cell.Cell(wb.active,
               value=f'=HYPERLINK("{elem.link}")' if elem.link else '') 
    linkcell.style = "Hyperlink"
    wb.active.append([elem.path,
                      elem.name,
                      elem.type.name,
                      '',
                      linkcell])

The error comes from the fact that Pylance can't be sure that calls to wb.active.cell won't return an invalid cell, so it applies all the restrictions it can for future code.

Upvotes: 1

Related Questions