From bd1a89b65ef9a283663186439758ce5030217e4e Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Mon, 6 Sep 2021 15:28:51 +1200 Subject: [PATCH] BUG: use TypeError (not OSError) when read_csv expects file path name or file-like object --- doc/source/whatsnew/v1.4.0.rst | 1 + pandas/_libs/parsers.pyx | 4 ++-- pandas/io/common.py | 4 ++++ pandas/tests/io/parser/common/test_common_basic.py | 8 ++++++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index bb9c124bae68b..c7aa0f2cddf9f 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -387,6 +387,7 @@ I/O - Column headers are dropped when constructing a :class:`DataFrame` from a sqlalchemy's ``Row`` object (:issue:`40682`) - Bug in unpickling a :class:`Index` with object dtype incorrectly inferring numeric dtypes (:issue:`43188`) - Bug in :func:`read_csv` where reading multi-header input with unequal lengths incorrectly raising uncontrolled ``IndexError`` (:issue:`43102`) +- Bug in :func:`read_csv`, changed exception class when expecting a file path name or file-like object from ``OSError`` to ``TypeError`` (:issue:`43443`) Period ^^^^^^ diff --git a/pandas/_libs/parsers.pyx b/pandas/_libs/parsers.pyx index 0c3918044a374..a7caa370859c2 100644 --- a/pandas/_libs/parsers.pyx +++ b/pandas/_libs/parsers.pyx @@ -607,8 +607,8 @@ cdef class TextReader: void *ptr if not hasattr(source, "read"): - raise IOError(f'Expected file path name or file-like object, ' - f'got {type(source)} type') + raise TypeError('Expected file path name or file-like object, ' + f'got {type(source)} type') ptr = new_rd_source(source) self.parser.source = ptr diff --git a/pandas/io/common.py b/pandas/io/common.py index 4e97eaf8b953c..882134b63c51d 100644 --- a/pandas/io/common.py +++ b/pandas/io/common.py @@ -738,6 +738,10 @@ def get_handle( isinstance(ioargs.filepath_or_buffer, str) or ioargs.should_close ) + if not hasattr(handle, "read"): + raise TypeError('Expected file path name or file-like object, ' + f'got {type(ioargs.filepath_or_buffer)} type') + handles.reverse() # close the most recently added buffer first if ioargs.should_close: assert not isinstance(ioargs.filepath_or_buffer, str) diff --git a/pandas/tests/io/parser/common/test_common_basic.py b/pandas/tests/io/parser/common/test_common_basic.py index 841df0ea7e470..24a20263a5886 100644 --- a/pandas/tests/io/parser/common/test_common_basic.py +++ b/pandas/tests/io/parser/common/test_common_basic.py @@ -493,6 +493,14 @@ def test_raise_on_sep_with_delim_whitespace(all_parsers): parser.read_csv(StringIO(data), sep=r"\s", delim_whitespace=True) +def test_read_filepath_or_buffer(all_parsers): + # see gh-43443 + parser = all_parsers + + with pytest.raises(TypeError, match="Expected file path name or file-lik"): + parser.read_csv(filepath_or_buffer=b'input') + + @xfail_pyarrow @pytest.mark.parametrize("delim_whitespace", [True, False]) def test_single_char_leading_whitespace(all_parsers, delim_whitespace):