Skip to content

Commit d6cb017

Browse files
committed
ENH: add __fspath__ to pandas own file-like objects
- HDFStore - ExcelFile (cherry picked from commit f9baec385e2513234a69a05031d2753899290d38)
1 parent f37d252 commit d6cb017

File tree

5 files changed

+39
-3
lines changed

5 files changed

+39
-3
lines changed

doc/source/whatsnew/v0.21.0.txt

+4-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ Check the :ref:`API Changes <whatsnew_0210.api_breaking>` and :ref:`deprecations
2020
New features
2121
~~~~~~~~~~~~
2222

23-
- Support for `PEP 519 -- Adding a file system path protocol <https://www.python.org/dev/peps/pep-0519/>`_ on most readers and writers (:issue:`13823`)
24-
23+
- Support for `PEP 519 -- Adding a file system path protocol
24+
<https://www.python.org/dev/peps/pep-0519/>`_ on most readers and writers (:issue:`13823`)
25+
- Added `__fspath__` method to :class`:pandas.HDFStore`, :class:`pandas.ExcelFile`,
26+
and :class:`pandas.ExcelWriter` to work properly with the file system path protocol (:issue:`13823`)
2527

2628

2729
.. _whatsnew_0210.enhancements.other:

pandas/io/excel.py

+6
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ def __init__(self, io, **kwds):
263263
raise ValueError('Must explicitly set engine if not passing in'
264264
' buffer or path for io.')
265265

266+
def __fspath__(self):
267+
return self._io
268+
266269
def parse(self, sheetname=0, header=0, skiprows=None, skip_footer=0,
267270
names=None, index_col=None, parse_cols=None, parse_dates=False,
268271
date_parser=None, na_values=None, thousands=None,
@@ -758,6 +761,9 @@ def __init__(self, path, engine=None,
758761
else:
759762
self.datetime_format = datetime_format
760763

764+
# def __fspath__(self):
765+
# return _stringify_path(self.path)
766+
761767
def _get_sheet_name(self, sheet_name):
762768
if sheet_name is None:
763769
sheet_name = self.cur_sheet

pandas/io/pytables.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ def __init__(self, path, mode=None, complevel=None, complib=None,
441441
"complib only supports {libs} compression.".format(
442442
libs=tables.filters.all_complibs))
443443

444-
self._path = path
444+
self._path = _stringify_path(path)
445445
if mode is None:
446446
mode = 'a'
447447
self._mode = mode
@@ -452,6 +452,9 @@ def __init__(self, path, mode=None, complevel=None, complib=None,
452452
self._filters = None
453453
self.open(mode=mode, **kwargs)
454454

455+
def __fspath__(self):
456+
return self._path
457+
455458
@property
456459
def root(self):
457460
""" return the root node """

pandas/tests/io/test_excel.py

+19
Original file line numberDiff line numberDiff line change
@@ -2499,3 +2499,22 @@ def custom_converter(css):
24992499
n_cells += 1
25002500

25012501
assert n_cells == (10 + 1) * (3 + 1)
2502+
2503+
2504+
class TestFSPath(object):
2505+
2506+
@pytest.mark.skipif(sys.version_info < (3, 6), reason='requires fspath')
2507+
def test_excelfile_fspath(self):
2508+
with tm.ensure_clean('foo.xlsx') as path:
2509+
df = DataFrame({"A": [1, 2]})
2510+
df.to_excel(path)
2511+
xl = ExcelFile(path)
2512+
result = os.fspath(xl)
2513+
assert result == path
2514+
2515+
@pytest.mark.skipif(sys.version_info < (3, 6), reason='requires fspath')
2516+
@pytest.mark.xfail
2517+
def test_excelwriter_fspath(self):
2518+
with tm.ensure_clean('foo.xlsx') as path:
2519+
writer = ExcelWriter(path)
2520+
assert os.fspath(writer) == str(path)

pandas/tests/io/test_pytables.py

+6
Original file line numberDiff line numberDiff line change
@@ -5154,6 +5154,12 @@ def test_query_compare_column_type(self):
51545154
expected = df.loc[[], :]
51555155
tm.assert_frame_equal(expected, result)
51565156

5157+
@pytest.mark.skipif(sys.version_info < (3, 6), reason="Need python 3.6")
5158+
def test_fspath(self):
5159+
with tm.ensure_clean('foo.h5') as path:
5160+
with pd.HDFStore(path) as store:
5161+
assert os.fspath(store) == str(path)
5162+
51575163

51585164
class TestHDFComplexValues(Base):
51595165
# GH10447

0 commit comments

Comments
 (0)