Skip to content

Commit 0e0f20f

Browse files
chrisburrNo-Stream
authored andcommitted
BUG: read_msgpack raise an error when passed an non existent path in Python 2 (pandas-dev#16523)
* TST: Add tests for trying to read non-existent files pandas-dev#15296 * BUG: Fix passing non-existant file to read_msgpack pandas-dev#15296 * TST: Fix io.test_common.test_read_non_existant for external modules * CLN: Import FileNotFoundError in tests/io/test_common.py
1 parent ab6b5ff commit 0e0f20f

File tree

3 files changed

+32
-8
lines changed

3 files changed

+32
-8
lines changed

doc/source/whatsnew/v0.22.0.txt

+2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ Documentation Changes
8787
Bug Fixes
8888
~~~~~~~~~
8989

90+
- Bug in ``pd.read_msgpack()`` with a non existent file is passed in Python 2 (:issue:`15296`)
91+
9092
Conversion
9193
^^^^^^^^^^
9294

pandas/io/packers.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,6 @@ def read(fh):
192192

193193
# see if we have an actual file
194194
if isinstance(path_or_buf, compat.string_types):
195-
196195
try:
197196
exists = os.path.exists(path_or_buf)
198197
except (TypeError, ValueError):
@@ -202,18 +201,21 @@ def read(fh):
202201
with open(path_or_buf, 'rb') as fh:
203202
return read(fh)
204203

205-
# treat as a binary-like
206204
if isinstance(path_or_buf, compat.binary_type):
205+
# treat as a binary-like
207206
fh = None
208207
try:
209-
fh = compat.BytesIO(path_or_buf)
210-
return read(fh)
208+
# We can't distinguish between a path and a buffer of bytes in
209+
# Python 2 so instead assume the first byte of a valid path is
210+
# less than 0x80.
211+
if compat.PY3 or ord(path_or_buf[0]) >= 0x80:
212+
fh = compat.BytesIO(path_or_buf)
213+
return read(fh)
211214
finally:
212215
if fh is not None:
213216
fh.close()
214-
215-
# a buffer like
216-
if hasattr(path_or_buf, 'read') and compat.callable(path_or_buf.read):
217+
elif hasattr(path_or_buf, 'read') and compat.callable(path_or_buf.read):
218+
# treat as a buffer like
217219
return read(path_or_buf)
218220

219221
raise ValueError('path_or_buf needs to be a string file path or file-like')

pandas/tests/io/test_common.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import pandas.util.testing as tm
1111

1212
from pandas.io import common
13-
from pandas.compat import is_platform_windows, StringIO
13+
from pandas.compat import is_platform_windows, StringIO, FileNotFoundError
1414

1515
from pandas import read_csv, concat
1616

@@ -125,6 +125,26 @@ def test_iterator(self):
125125
tm.assert_frame_equal(first, expected.iloc[[0]])
126126
tm.assert_frame_equal(concat(it), expected.iloc[1:])
127127

128+
@pytest.mark.parametrize('reader, module, error_class, fn_ext', [
129+
(pd.read_csv, 'os', FileNotFoundError, 'csv'),
130+
(pd.read_table, 'os', FileNotFoundError, 'csv'),
131+
(pd.read_fwf, 'os', FileNotFoundError, 'txt'),
132+
(pd.read_excel, 'xlrd', FileNotFoundError, 'xlsx'),
133+
(pd.read_feather, 'feather', Exception, 'feather'),
134+
(pd.read_hdf, 'tables', FileNotFoundError, 'h5'),
135+
(pd.read_stata, 'os', FileNotFoundError, 'dta'),
136+
(pd.read_sas, 'os', FileNotFoundError, 'sas7bdat'),
137+
(pd.read_json, 'os', ValueError, 'json'),
138+
(pd.read_msgpack, 'os', ValueError, 'mp'),
139+
(pd.read_pickle, 'os', FileNotFoundError, 'pickle'),
140+
])
141+
def test_read_non_existant(self, reader, module, error_class, fn_ext):
142+
pytest.importorskip(module)
143+
144+
path = os.path.join(HERE, 'data', 'does_not_exist.' + fn_ext)
145+
with pytest.raises(error_class):
146+
reader(path)
147+
128148
@pytest.mark.parametrize('reader, module, path', [
129149
(pd.read_csv, 'os', os.path.join(HERE, 'data', 'iris.csv')),
130150
(pd.read_table, 'os', os.path.join(HERE, 'data', 'iris.csv')),

0 commit comments

Comments
 (0)