From 9931f3805704ac1464e149fb998ff2ec41bf6cb0 Mon Sep 17 00:00:00 2001 From: Daniel Huppmann Date: Sun, 8 Dec 2019 00:07:47 +0100 Subject: [PATCH] Bugfix for writing `to_excel` with `pd.ExcelWriter` (#301) * add unit test for bug #300 * insert bugfix * add to release notes --- RELEASE_NOTES.md | 1 + pyam/core.py | 3 +++ tests/test_io.py | 24 +++++++++++++----------- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index dc39b5239..e95d1ea12 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,6 +1,7 @@ # Next Release +- [#301](https://github.com/IAMconsortium/pyam/pull/301) Bugfix when using `to_excel()` with a `pd.ExcelWriter` - [#297](https://github.com/IAMconsortium/pyam/pull/297) Add `empty` attribute, better error for `timeseries()` on empty dataframe - [#295](https://github.com/IAMconsortium/pyam/pull/295) Include `meta` table when writing to or reading from `xlsx` files - [#292](https://github.com/IAMconsortium/pyam/pull/292) Add warning message if `data` is empty at initialization (after formatting) diff --git a/pyam/core.py b/pyam/core.py index 0e7b3905a..4da8c568b 100644 --- a/pyam/core.py +++ b/pyam/core.py @@ -1161,6 +1161,7 @@ def to_excel(self, excel_writer, sheet_name='data', iamc_index=False, if True, write :code:`meta` to an Excel sheet 'meta' (default); if this is a string, use it as sheet name """ + close = False if not isinstance(excel_writer, pd.ExcelWriter): close = True excel_writer = pd.ExcelWriter(excel_writer) @@ -1171,6 +1172,8 @@ def to_excel(self, excel_writer, sheet_name='data', iamc_index=False, include_meta = 'meta' if include_meta is True else include_meta if isstr(include_meta): write_sheet(excel_writer, include_meta, self.meta, index=True) + + # close the file if `excel_writer` arg was a file name if close: excel_writer.close() diff --git a/tests/test_io.py b/tests/test_io.py index 71c283ee8..2fd585350 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -29,18 +29,20 @@ def test_io_xlsx(meta_df, meta_args): # add column to `meta` meta_df.set_meta(['a', 'b'], 'string') - # write to xlsx + # write to xlsx (direct file name and ExcelWriter, see bug report #300) file = 'testing_io_write_read.xlsx' - meta_df.to_excel(file, **meta_args[0]) - - # read from xlsx - import_df = IamDataFrame(file, **meta_args[1]) - - # assert that `data` and `meta` tables are equal and delete file - pd.testing.assert_frame_equal(meta_df.data, import_df.data) - pd.testing.assert_frame_equal(meta_df.meta, import_df.meta) - - os.remove(file) + for f in [file, pd.ExcelWriter(file)]: + meta_df.to_excel(f, **meta_args[0]) + if isinstance(f, pd.ExcelWriter): + f.close() + + # read from xlsx + import_df = IamDataFrame(file, **meta_args[1]) + + # assert that `data` and `meta` tables are equal and delete file + pd.testing.assert_frame_equal(meta_df.data, import_df.data) + pd.testing.assert_frame_equal(meta_df.meta, import_df.meta) + os.remove(file) @pytest.mark.parametrize("args", [{}, dict(sheet_name='meta')])