Skip to content

Commit

Permalink
BUG: file leak in read_excel (pandas-dev#30096)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel authored and proost committed Dec 19, 2019
1 parent 91aad05 commit 4d82e5d
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 0 deletions.
10 changes: 10 additions & 0 deletions pandas/io/excel/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,12 @@ def sheet_names(self):

def close(self):
"""close io if necessary"""
if self.engine == "openpyxl":
# https://stackoverflow.com/questions/31416842/
# openpyxl-does-not-close-excel-workbook-in-read-only-mode
wb = self.book
wb._archive.close()

if hasattr(self.io, "close"):
self.io.close()

Expand All @@ -900,3 +906,7 @@ def __enter__(self):

def __exit__(self, exc_type, exc_value, traceback):
self.close()

def __del__(self):
# Ensure we don't leak file descriptors
self.close()
2 changes: 2 additions & 0 deletions pandas/tests/io/excel/test_readers.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ def test_read_from_pathlib_path(self, read_ext):
tm.assert_frame_equal(expected, actual)

@td.skip_if_no("py.path")
@td.check_file_leaks
def test_read_from_py_localpath(self, read_ext):

# GH12655
Expand Down Expand Up @@ -881,6 +882,7 @@ def test_excel_passes_na_filter(self, read_ext, na_filter):
tm.assert_frame_equal(parsed, expected)

@pytest.mark.parametrize("arg", ["sheet", "sheetname", "parse_cols"])
@td.check_file_leaks
def test_unexpected_kwargs_raises(self, read_ext, arg):
# gh-17964
kwarg = {arg: "Sheet1"}
Expand Down
1 change: 1 addition & 0 deletions pandas/tests/io/excel/test_writers.py
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ def test_to_excel_unicode_filename(self, ext, path):
)
tm.assert_frame_equal(result, expected)

# FIXME: dont leave commented-out
# def test_to_excel_header_styling_xls(self, engine, ext):

# import StringIO
Expand Down
22 changes: 22 additions & 0 deletions pandas/util/_test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def test_foo():
For more information, refer to the ``pytest`` documentation on ``skipif``.
"""
from distutils.version import LooseVersion
from functools import wraps
import locale
from typing import Callable, Optional

Expand Down Expand Up @@ -230,3 +231,24 @@ def documented_fixture(fixture):
return fixture

return documented_fixture


def check_file_leaks(func):
"""
Decorate a test function tot check that we are not leaking file descriptors.
"""
psutil = safe_import("psutil")
if not psutil:
return func

@wraps(func)
def new_func(*args, **kwargs):
proc = psutil.Process()
flist = proc.open_files()

func(*args, **kwargs)

flist2 = proc.open_files()
assert flist2 == flist

return new_func

0 comments on commit 4d82e5d

Please sign in to comment.