Read-only archives not always closed when the workbook is closed on Windows
When opening a workbook in read-only mode AND reading a value from a cell, AND the cell is not empty, a file handle is leaked. If the cell is empty, or if the workbook is empty, or if we don't use read-only mode, the problem goes away. If we don't try to clean up our temporary files, the problem is still there, but hidden.
def problem() -> None:
book_path = Path("value.xlsx")
tmp_book_path = Path("tmp.xlsx")
copyfile(src=book_path, dst=tmp_book_path)
book: Workbook = load_workbook(
filename=tmp_book_path,
read_only=True, # Changing this to False makes the problem go away.
data_only=True,
)
# Commenting out the next line or changing "A1" to "A2" makes the
problem go away.
print(book["Sheet1"]["A1"].value)
book.close()
# This fails because something is still using the file.
tmp_book_path.unlink(missing_ok=True)
empty.xlsx and value.xlsx are attached
In practice, our code looks closer to this:
from pathlib import Path
from shutil import copyfile
from openpyxl import load_workbook, Workbook
def problem():
wb = Workbook()
wb.save("value.xlsx")
wb.close()
book_path = Path("value.xlsx")
tmp_book_path = Path("tmp.xlsx")
copyfile(src=book_path, dst=tmp_book_path)
book = load_workbook(
filename=tmp_book_path,
read_only=True, # Changing this to False makes the problem go away.
data_only=True,
)
# Commenting out the next line or changing "A1" to "A2" makes the problem go away.
print(book["Sheet"]["A1"].value)
book.close()
# This fails because something is still using the file.
tmp_book_path.unlink(missing_ok=True)
if __name__ == "__main__":
problem()
Edited by CharlieC