Skip to content

Commit cc7bbd2

Browse files
author
Adrien Di Mascio
committed
BUG: close hdf store on any error
In `read_hdf`, if the `store.select()` call throws either a `ValueError`, a `TypeError` or a `KeyError` then the store is closed. However, if any other exception is thrown (e.g. an `AssertionError` if there are gaps in blocks ref_loc) , the store is not closed and some client code could end up trying to reopen the store and hit an error like: `the file XXX is already opened. Please close it before reopening in write mode`. Furthermore, the exception is re-raised in all cases. This commit just closes store in all cases. Closes #28430
1 parent a880e42 commit cc7bbd2

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

pandas/io/pytables.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ def read_hdf(path_or_buf, key=None, mode="r", **kwargs):
404404
)
405405
key = candidate_only_group._v_pathname
406406
return store.select(key, auto_close=auto_close, **kwargs)
407-
except (ValueError, TypeError, KeyError):
407+
finally:
408408
# if there is an error, close the store
409409
try:
410410
store.close()

pandas/tests/io/pytables/test_pytables.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,25 @@ def check_default_mode():
562562
check("w")
563563
check_default_mode()
564564

565+
def test_store_closed_on_error(self, mocker):
566+
"""check hdf store is closed whichever error occurs"""
567+
mocker.patch("pandas.io.pytables.HDFStore.select").side_effect = AssertionError(
568+
"Gaps in blk ref_locs"
569+
)
570+
df = tm.makeDataFrame()
571+
with ensure_clean_path(self.path) as path:
572+
df.to_hdf(path, "df")
573+
try:
574+
pd.read_hdf(path, "df")
575+
except AssertionError: # this is expected, because of our mock
576+
pass
577+
try:
578+
HDFStore(path, mode="w")
579+
except ValueError as exc:
580+
pytest.fail(
581+
"store not closed properly, got error {exc}".format(exc=exc)
582+
)
583+
565584
def test_reopen_handle(self):
566585

567586
with ensure_clean_path(self.path) as path:

0 commit comments

Comments
 (0)