diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index ac9f8b02c7acb..61848cb127029 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -819,6 +819,7 @@ I/O - Bug in :func:`read_excel` when reading a ``.ods`` file with newlines between xml elements (:issue:`45598`) - Bug in :func:`read_parquet` when ``engine="fastparquet"`` where the file was not closed on error (:issue:`46555`) - :meth:`to_html` now excludes the ``border`` attribute from ```` elements when ``border`` keyword is set to ``False``. +- Bug in :func:`read_sas` returned ``None`` rather than an empty DataFrame for SAS7BDAT files with zero rows (:issue:`18198`) - Period diff --git a/pandas/io/sas/sas7bdat.py b/pandas/io/sas/sas7bdat.py index debd686475432..1e071690d35fb 100644 --- a/pandas/io/sas/sas7bdat.py +++ b/pandas/io/sas/sas7bdat.py @@ -737,7 +737,7 @@ def read(self, nrows: int | None = None) -> DataFrame | None: self.close() raise EmptyDataError("No columns to parse from file") - if self._current_row_in_file_index >= self.row_count: + if nrows > 0 and self._current_row_in_file_index >= self.row_count: return None m = self.row_count - self._current_row_in_file_index diff --git a/pandas/tests/io/sas/data/zero_rows.sas7bdat b/pandas/tests/io/sas/data/zero_rows.sas7bdat new file mode 100644 index 0000000000000..a5ba95b639507 Binary files /dev/null and b/pandas/tests/io/sas/data/zero_rows.sas7bdat differ diff --git a/pandas/tests/io/sas/test_sas7bdat.py b/pandas/tests/io/sas/test_sas7bdat.py index 0dd1fa175fa3f..2b3ccf57d3959 100644 --- a/pandas/tests/io/sas/test_sas7bdat.py +++ b/pandas/tests/io/sas/test_sas7bdat.py @@ -216,6 +216,14 @@ def test_zero_variables(datapath): pd.read_sas(fname) +def test_zero_rows(datapath): + # GH 18198 + fname = datapath("io", "sas", "data", "zero_rows.sas7bdat") + result = pd.read_sas(fname) + expected = pd.DataFrame([{"char_field": "a", "num_field": 1.0}]).iloc[:0] + tm.assert_frame_equal(result, expected) + + def test_corrupt_read(datapath): # We don't really care about the exact failure, the important thing is # that the resource should be cleaned up afterwards (BUG #35566)