diff --git a/doc/source/whatsnew/v0.17.0.txt b/doc/source/whatsnew/v0.17.0.txt index 2f5388381a103..09a39a6d9b2f5 100644 --- a/doc/source/whatsnew/v0.17.0.txt +++ b/doc/source/whatsnew/v0.17.0.txt @@ -131,3 +131,4 @@ Bug Fixes - Bug in ``DatetimeIndex`` and ``PeriodIndex.value_counts`` resets name from its result, but retains in result's ``Index``. (:issue:`10150`) - Bug in `pandas.concat` with ``axis=0`` when column is of dtype ``category`` (:issue:`10177`) +- Bug in ``read_msgpack`` where input type is not always checked (:issue:`10369`) diff --git a/pandas/io/packers.py b/pandas/io/packers.py index 75ca44fd1ef3e..f5e000449f232 100644 --- a/pandas/io/packers.py +++ b/pandas/io/packers.py @@ -141,24 +141,28 @@ def read(fh): try: exists = os.path.exists(path_or_buf) - except (TypeError,ValueError): + except (TypeError, ValueError): exists = False if exists: with open(path_or_buf, 'rb') as fh: return read(fh) - # treat as a string-like - if not hasattr(path_or_buf, 'read'): - + # treat as a binary-like + if isinstance(path_or_buf, compat.binary_type): + fh = None try: fh = compat.BytesIO(path_or_buf) return read(fh) finally: - fh.close() + if fh is not None: + fh.close() # a buffer like - return read(path_or_buf) + if hasattr(path_or_buf, 'read') and compat.callable(path_or_buf.read): + return read(path_or_buf) + + raise ValueError('path_or_buf needs to be a string file path or file-like') dtype_dict = {21: np.dtype('M8[ns]'), u('datetime64[ns]'): np.dtype('M8[ns]'), diff --git a/pandas/io/tests/test_packers.py b/pandas/io/tests/test_packers.py index 92e0d7ba1a338..9f1fd41e90413 100644 --- a/pandas/io/tests/test_packers.py +++ b/pandas/io/tests/test_packers.py @@ -93,6 +93,17 @@ def test_iterator_with_string_io(self): for i, result in enumerate(read_msgpack(s,iterator=True)): tm.assert_frame_equal(result,dfs[i]) + def test_invalid_arg(self): + #GH10369 + class A(object): + def __init__(self): + self.read = 0 + + tm.assertRaises(ValueError, read_msgpack, path_or_buf=None) + tm.assertRaises(ValueError, read_msgpack, path_or_buf={}) + tm.assertRaises(ValueError, read_msgpack, path_or_buf=A()) + + class TestNumpy(TestPackers): def test_numpy_scalar_float(self):