From 53f7f132cc0aee78d30f297fc4322b94a9ebb7c4 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Mon, 19 Feb 2024 16:08:51 -0800 Subject: [PATCH 1/4] Revert "CI: Run excel tests on single cpu for windows (#57486)" This reverts commit 9c02050a553eea87d7f3ac09b74f809dda0afa62. --- pandas/tests/io/excel/test_odf.py | 5 ----- pandas/tests/io/excel/test_odswriter.py | 5 ----- pandas/tests/io/excel/test_openpyxl.py | 5 ----- pandas/tests/io/excel/test_readers.py | 4 ---- pandas/tests/io/excel/test_style.py | 4 ---- pandas/tests/io/excel/test_writers.py | 4 ---- pandas/tests/io/excel/test_xlrd.py | 5 ----- pandas/tests/io/excel/test_xlsxwriter.py | 5 ----- 8 files changed, 37 deletions(-) diff --git a/pandas/tests/io/excel/test_odf.py b/pandas/tests/io/excel/test_odf.py index b5bb9b27258d8..f01827fa4ca2f 100644 --- a/pandas/tests/io/excel/test_odf.py +++ b/pandas/tests/io/excel/test_odf.py @@ -3,16 +3,11 @@ import numpy as np import pytest -from pandas.compat import is_platform_windows - import pandas as pd import pandas._testing as tm pytest.importorskip("odf") -if is_platform_windows(): - pytestmark = pytest.mark.single_cpu - @pytest.fixture(autouse=True) def cd_and_set_engine(monkeypatch, datapath): diff --git a/pandas/tests/io/excel/test_odswriter.py b/pandas/tests/io/excel/test_odswriter.py index 1c728ad801bc1..271353a173d2a 100644 --- a/pandas/tests/io/excel/test_odswriter.py +++ b/pandas/tests/io/excel/test_odswriter.py @@ -6,8 +6,6 @@ import pytest -from pandas.compat import is_platform_windows - import pandas as pd import pandas._testing as tm @@ -15,9 +13,6 @@ odf = pytest.importorskip("odf") -if is_platform_windows(): - pytestmark = pytest.mark.single_cpu - @pytest.fixture def ext(): diff --git a/pandas/tests/io/excel/test_openpyxl.py b/pandas/tests/io/excel/test_openpyxl.py index 952026b2a50d3..c20c6daf92931 100644 --- a/pandas/tests/io/excel/test_openpyxl.py +++ b/pandas/tests/io/excel/test_openpyxl.py @@ -5,8 +5,6 @@ import numpy as np import pytest -from pandas.compat import is_platform_windows - import pandas as pd from pandas import DataFrame import pandas._testing as tm @@ -19,9 +17,6 @@ openpyxl = pytest.importorskip("openpyxl") -if is_platform_windows(): - pytestmark = pytest.mark.single_cpu - @pytest.fixture def ext(): diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index 2cf17913ba6e4..e4a8791396ee2 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -18,7 +18,6 @@ from pandas._config import using_pyarrow_string_dtype -from pandas.compat import is_platform_windows import pandas.util._test_decorators as td import pandas as pd @@ -35,9 +34,6 @@ StringArray, ) -if is_platform_windows(): - pytestmark = pytest.mark.single_cpu - read_ext_params = [".xls", ".xlsx", ".xlsm", ".xlsb", ".ods"] engine_params = [ # Add any engines to test here diff --git a/pandas/tests/io/excel/test_style.py b/pandas/tests/io/excel/test_style.py index e801d1c647ed1..58b297e4520bb 100644 --- a/pandas/tests/io/excel/test_style.py +++ b/pandas/tests/io/excel/test_style.py @@ -4,7 +4,6 @@ import numpy as np import pytest -from pandas.compat import is_platform_windows import pandas.util._test_decorators as td from pandas import ( @@ -21,9 +20,6 @@ # could compute styles and render to excel without jinja2, since there is no # 'template' file, but this needs the import error to delayed until render time. -if is_platform_windows(): - pytestmark = pytest.mark.single_cpu - def assert_equal_cell_styles(cell1, cell2): # TODO: should find a better way to check equality diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 7d958d2d35920..3352164b2f980 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -11,7 +11,6 @@ import numpy as np import pytest -from pandas.compat import is_platform_windows from pandas.compat._constants import PY310 from pandas.compat._optional import import_optional_dependency import pandas.util._test_decorators as td @@ -35,9 +34,6 @@ ) from pandas.io.excel._util import _writers -if is_platform_windows(): - pytestmark = pytest.mark.single_cpu - def get_exp_unit(path: str) -> str: return "ns" diff --git a/pandas/tests/io/excel/test_xlrd.py b/pandas/tests/io/excel/test_xlrd.py index edabbad93acbc..c49cbaf7fb26c 100644 --- a/pandas/tests/io/excel/test_xlrd.py +++ b/pandas/tests/io/excel/test_xlrd.py @@ -3,8 +3,6 @@ import numpy as np import pytest -from pandas.compat import is_platform_windows - import pandas as pd import pandas._testing as tm @@ -13,9 +11,6 @@ xlrd = pytest.importorskip("xlrd") -if is_platform_windows(): - pytestmark = pytest.mark.single_cpu - @pytest.fixture def read_ext_xlrd(): diff --git a/pandas/tests/io/excel/test_xlsxwriter.py b/pandas/tests/io/excel/test_xlsxwriter.py index 529367761fc02..94f6bdfaf069c 100644 --- a/pandas/tests/io/excel/test_xlsxwriter.py +++ b/pandas/tests/io/excel/test_xlsxwriter.py @@ -2,8 +2,6 @@ import pytest -from pandas.compat import is_platform_windows - from pandas import DataFrame import pandas._testing as tm @@ -11,9 +9,6 @@ xlsxwriter = pytest.importorskip("xlsxwriter") -if is_platform_windows(): - pytestmark = pytest.mark.single_cpu - @pytest.fixture def ext(): From 85b7b2ca0c2165a40f40cabc52f9d14ef4550359 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Mon, 19 Feb 2024 17:16:59 -0800 Subject: [PATCH 2/4] Use tmp_path fixture --- pandas/tests/io/excel/test_odswriter.py | 93 +-- pandas/tests/io/excel/test_openpyxl.py | 276 +++---- pandas/tests/io/excel/test_readers.py | 62 +- pandas/tests/io/excel/test_style.py | 273 ++++--- pandas/tests/io/excel/test_writers.py | 874 ++++++++++++----------- pandas/tests/io/excel/test_xlsxwriter.py | 87 +-- 6 files changed, 837 insertions(+), 828 deletions(-) diff --git a/pandas/tests/io/excel/test_odswriter.py b/pandas/tests/io/excel/test_odswriter.py index 271353a173d2a..b319de3235ce3 100644 --- a/pandas/tests/io/excel/test_odswriter.py +++ b/pandas/tests/io/excel/test_odswriter.py @@ -7,7 +7,6 @@ import pytest import pandas as pd -import pandas._testing as tm from pandas.io.excel import ExcelWriter @@ -19,42 +18,47 @@ def ext(): return ".ods" -def test_write_append_mode_raises(ext): +@pytest.fixture +def tmp_excel(ext, tmp_path): + tmp = tmp_path / f"tmp{ext}" + tmp.touch() + yield str(tmp) + tmp.unlink() + + +def test_write_append_mode_raises(tmp_excel): msg = "Append mode is not supported with odf!" - with tm.ensure_clean(ext) as f: - with pytest.raises(ValueError, match=msg): - ExcelWriter(f, engine="odf", mode="a") + with pytest.raises(ValueError, match=msg): + ExcelWriter(tmp_excel, engine="odf", mode="a") @pytest.mark.parametrize("engine_kwargs", [None, {"kwarg": 1}]) -def test_engine_kwargs(ext, engine_kwargs): +def test_engine_kwargs(tmp_excel, engine_kwargs): # GH 42286 # GH 43445 # test for error: OpenDocumentSpreadsheet does not accept any arguments - with tm.ensure_clean(ext) as f: - if engine_kwargs is not None: - error = re.escape( - "OpenDocumentSpreadsheet() got an unexpected keyword argument 'kwarg'" - ) - with pytest.raises( - TypeError, - match=error, - ): - ExcelWriter(f, engine="odf", engine_kwargs=engine_kwargs) - else: - with ExcelWriter(f, engine="odf", engine_kwargs=engine_kwargs) as _: - pass - - -def test_book_and_sheets_consistent(ext): + if engine_kwargs is not None: + error = re.escape( + "OpenDocumentSpreadsheet() got an unexpected keyword argument 'kwarg'" + ) + with pytest.raises( + TypeError, + match=error, + ): + ExcelWriter(tmp_excel, engine="odf", engine_kwargs=engine_kwargs) + else: + with ExcelWriter(tmp_excel, engine="odf", engine_kwargs=engine_kwargs) as _: + pass + + +def test_book_and_sheets_consistent(tmp_excel): # GH#45687 - Ensure sheets is updated if user modifies book - with tm.ensure_clean(ext) as f: - with ExcelWriter(f) as writer: - assert writer.sheets == {} - table = odf.table.Table(name="test_name") - writer.book.spreadsheet.addElement(table) - assert writer.sheets == {"test_name": table} + with ExcelWriter(tmp_excel) as writer: + assert writer.sheets == {} + table = odf.table.Table(name="test_name") + writer.book.spreadsheet.addElement(table) + assert writer.sheets == {"test_name": table} @pytest.mark.parametrize( @@ -73,7 +77,9 @@ def test_book_and_sheets_consistent(ext): (date(2010, 10, 10), "date", "date-value", "2010-10-10"), ], ) -def test_cell_value_type(ext, value, cell_value_type, cell_value_attribute, cell_value): +def test_cell_value_type( + tmp_excel, value, cell_value_type, cell_value_attribute, cell_value +): # GH#54994 ODS: cell attributes should follow specification # http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html#refTable13 from odf.namespaces import OFFICENS @@ -84,18 +90,17 @@ def test_cell_value_type(ext, value, cell_value_type, cell_value_attribute, cell table_cell_name = TableCell().qname - with tm.ensure_clean(ext) as f: - pd.DataFrame([[value]]).to_excel(f, header=False, index=False) - - with pd.ExcelFile(f) as wb: - sheet = wb._reader.get_sheet_by_index(0) - sheet_rows = sheet.getElementsByType(TableRow) - sheet_cells = [ - x - for x in sheet_rows[0].childNodes - if hasattr(x, "qname") and x.qname == table_cell_name - ] - - cell = sheet_cells[0] - assert cell.attributes.get((OFFICENS, "value-type")) == cell_value_type - assert cell.attributes.get((OFFICENS, cell_value_attribute)) == cell_value + pd.DataFrame([[value]]).to_excel(tmp_excel, header=False, index=False) + + with pd.ExcelFile(tmp_excel) as wb: + sheet = wb._reader.get_sheet_by_index(0) + sheet_rows = sheet.getElementsByType(TableRow) + sheet_cells = [ + x + for x in sheet_rows[0].childNodes + if hasattr(x, "qname") and x.qname == table_cell_name + ] + + cell = sheet_cells[0] + assert cell.attributes.get((OFFICENS, "value-type")) == cell_value_type + assert cell.attributes.get((OFFICENS, cell_value_attribute)) == cell_value diff --git a/pandas/tests/io/excel/test_openpyxl.py b/pandas/tests/io/excel/test_openpyxl.py index c20c6daf92931..16e6002f75e75 100644 --- a/pandas/tests/io/excel/test_openpyxl.py +++ b/pandas/tests/io/excel/test_openpyxl.py @@ -23,6 +23,14 @@ def ext(): return ".xlsx" +@pytest.fixture +def tmp_excel(ext, tmp_path): + tmp = tmp_path / f"tmp{ext}" + tmp.touch() + yield str(tmp) + tmp.unlink() + + def test_to_excel_styleconverter(): from openpyxl import styles @@ -56,7 +64,7 @@ def test_to_excel_styleconverter(): assert kw["protection"] == protection -def test_write_cells_merge_styled(ext): +def test_write_cells_merge_styled(tmp_excel): from pandas.io.formats.excel import ExcelCell sheet_name = "merge_styled" @@ -78,72 +86,73 @@ def test_write_cells_merge_styled(ext): ) ] - with tm.ensure_clean(ext) as path: - with _OpenpyxlWriter(path) as writer: - writer._write_cells(initial_cells, sheet_name=sheet_name) - writer._write_cells(merge_cells, sheet_name=sheet_name) + with _OpenpyxlWriter(tmp_excel) as writer: + writer._write_cells(initial_cells, sheet_name=sheet_name) + writer._write_cells(merge_cells, sheet_name=sheet_name) - wks = writer.sheets[sheet_name] - xcell_b1 = wks["B1"] - xcell_a2 = wks["A2"] - assert xcell_b1.font == openpyxl_sty_merged - assert xcell_a2.font == openpyxl_sty_merged + wks = writer.sheets[sheet_name] + xcell_b1 = wks["B1"] + xcell_a2 = wks["A2"] + assert xcell_b1.font == openpyxl_sty_merged + assert xcell_a2.font == openpyxl_sty_merged @pytest.mark.parametrize("iso_dates", [True, False]) -def test_engine_kwargs_write(ext, iso_dates): +def test_engine_kwargs_write(tmp_excel, iso_dates): # GH 42286 GH 43445 engine_kwargs = {"iso_dates": iso_dates} - with tm.ensure_clean(ext) as f: - with ExcelWriter(f, engine="openpyxl", engine_kwargs=engine_kwargs) as writer: - assert writer.book.iso_dates == iso_dates - # ExcelWriter won't allow us to close without writing something - DataFrame().to_excel(writer) + with ExcelWriter( + tmp_excel, engine="openpyxl", engine_kwargs=engine_kwargs + ) as writer: + assert writer.book.iso_dates == iso_dates + # ExcelWriter won't allow us to close without writing something + DataFrame().to_excel(writer) -def test_engine_kwargs_append_invalid(ext): +def test_engine_kwargs_append_invalid(tmp_excel): # GH 43445 # test whether an invalid engine kwargs actually raises - with tm.ensure_clean(ext) as f: - DataFrame(["hello", "world"]).to_excel(f) - with pytest.raises( - TypeError, - match=re.escape( - "load_workbook() got an unexpected keyword argument 'apple_banana'" - ), - ): - with ExcelWriter( - f, engine="openpyxl", mode="a", engine_kwargs={"apple_banana": "fruit"} - ) as writer: - # ExcelWriter needs us to write something to close properly - DataFrame(["good"]).to_excel(writer, sheet_name="Sheet2") + DataFrame(["hello", "world"]).to_excel(tmp_excel) + with pytest.raises( + TypeError, + match=re.escape( + "load_workbook() got an unexpected keyword argument 'apple_banana'" + ), + ): + with ExcelWriter( + tmp_excel, + engine="openpyxl", + mode="a", + engine_kwargs={"apple_banana": "fruit"}, + ) as writer: + # ExcelWriter needs us to write something to close properly + DataFrame(["good"]).to_excel(writer, sheet_name="Sheet2") @pytest.mark.parametrize("data_only, expected", [(True, 0), (False, "=1+1")]) -def test_engine_kwargs_append_data_only(ext, data_only, expected): +def test_engine_kwargs_append_data_only(tmp_excel, data_only, expected): # GH 43445 # tests whether the data_only engine_kwarg actually works well for # openpyxl's load_workbook - with tm.ensure_clean(ext) as f: - DataFrame(["=1+1"]).to_excel(f) - with ExcelWriter( - f, engine="openpyxl", mode="a", engine_kwargs={"data_only": data_only} - ) as writer: - assert writer.sheets["Sheet1"]["B2"].value == expected - # ExcelWriter needs us to writer something to close properly? - DataFrame().to_excel(writer, sheet_name="Sheet2") - - # ensure that data_only also works for reading - # and that formulas/values roundtrip - assert ( - pd.read_excel( - f, - sheet_name="Sheet1", - engine="openpyxl", - engine_kwargs={"data_only": data_only}, - ).iloc[0, 1] - == expected - ) + DataFrame(["=1+1"]).to_excel(tmp_excel) + with ExcelWriter( + tmp_excel, engine="openpyxl", mode="a", engine_kwargs={"data_only": data_only} + ) as writer: + assert writer.sheets["Sheet1"]["B2"].value == expected + # ExcelWriter needs us to writer something to close properly? + DataFrame().to_excel(writer, sheet_name="Sheet2") + + # ensure that data_only also works for reading + # and that formulas/values roundtrip + assert ( + pd.read_excel( + tmp_excel, + sheet_name="Sheet1", + engine="openpyxl", + engine_kwargs={"data_only": data_only}, + ).iloc[0, 1] + == expected + ) @pytest.mark.parametrize("kwarg_name", ["read_only", "data_only"]) @@ -162,26 +171,25 @@ def test_engine_kwargs_append_reader(datapath, ext, kwarg_name, kwarg_value): @pytest.mark.parametrize( "mode,expected", [("w", ["baz"]), ("a", ["foo", "bar", "baz"])] ) -def test_write_append_mode(ext, mode, expected): +def test_write_append_mode(tmp_excel, mode, expected): df = DataFrame([1], columns=["baz"]) - with tm.ensure_clean(ext) as f: - wb = openpyxl.Workbook() - wb.worksheets[0].title = "foo" - wb.worksheets[0]["A1"].value = "foo" - wb.create_sheet("bar") - wb.worksheets[1]["A1"].value = "bar" - wb.save(f) + wb = openpyxl.Workbook() + wb.worksheets[0].title = "foo" + wb.worksheets[0]["A1"].value = "foo" + wb.create_sheet("bar") + wb.worksheets[1]["A1"].value = "bar" + wb.save(tmp_excel) - with ExcelWriter(f, engine="openpyxl", mode=mode) as writer: - df.to_excel(writer, sheet_name="baz", index=False) + with ExcelWriter(tmp_excel, engine="openpyxl", mode=mode) as writer: + df.to_excel(writer, sheet_name="baz", index=False) - with contextlib.closing(openpyxl.load_workbook(f)) as wb2: - result = [sheet.title for sheet in wb2.worksheets] - assert result == expected + with contextlib.closing(openpyxl.load_workbook(tmp_excel)) as wb2: + result = [sheet.title for sheet in wb2.worksheets] + assert result == expected - for index, cell_value in enumerate(expected): - assert wb2.worksheets[index]["A1"].value == cell_value + for index, cell_value in enumerate(expected): + assert wb2.worksheets[index]["A1"].value == cell_value @pytest.mark.parametrize( @@ -192,26 +200,25 @@ def test_write_append_mode(ext, mode, expected): ("overlay", 1, ["pear", "banana"]), ], ) -def test_if_sheet_exists_append_modes(ext, if_sheet_exists, num_sheets, expected): +def test_if_sheet_exists_append_modes(tmp_excel, if_sheet_exists, num_sheets, expected): # GH 40230 df1 = DataFrame({"fruit": ["apple", "banana"]}) df2 = DataFrame({"fruit": ["pear"]}) - with tm.ensure_clean(ext) as f: - df1.to_excel(f, engine="openpyxl", sheet_name="foo", index=False) - with ExcelWriter( - f, engine="openpyxl", mode="a", if_sheet_exists=if_sheet_exists - ) as writer: - df2.to_excel(writer, sheet_name="foo", index=False) + df1.to_excel(tmp_excel, engine="openpyxl", sheet_name="foo", index=False) + with ExcelWriter( + tmp_excel, engine="openpyxl", mode="a", if_sheet_exists=if_sheet_exists + ) as writer: + df2.to_excel(writer, sheet_name="foo", index=False) - with contextlib.closing(openpyxl.load_workbook(f)) as wb: - assert len(wb.sheetnames) == num_sheets - assert wb.sheetnames[0] == "foo" - result = pd.read_excel(wb, "foo", engine="openpyxl") - assert list(result["fruit"]) == expected - if len(wb.sheetnames) == 2: - result = pd.read_excel(wb, wb.sheetnames[1], engine="openpyxl") - tm.assert_frame_equal(result, df2) + with contextlib.closing(openpyxl.load_workbook(tmp_excel)) as wb: + assert len(wb.sheetnames) == num_sheets + assert wb.sheetnames[0] == "foo" + result = pd.read_excel(wb, "foo", engine="openpyxl") + assert list(result["fruit"]) == expected + if len(wb.sheetnames) == 2: + result = pd.read_excel(wb, wb.sheetnames[1], engine="openpyxl") + tm.assert_frame_equal(result, df2) @pytest.mark.parametrize( @@ -223,28 +230,29 @@ def test_if_sheet_exists_append_modes(ext, if_sheet_exists, num_sheets, expected (1, 1, ["hello", "world"], ["goodbye", "poop"]), ], ) -def test_append_overlay_startrow_startcol(ext, startrow, startcol, greeting, goodbye): +def test_append_overlay_startrow_startcol( + tmp_excel, startrow, startcol, greeting, goodbye +): df1 = DataFrame({"greeting": ["hello", "world"], "goodbye": ["goodbye", "people"]}) df2 = DataFrame(["poop"]) - with tm.ensure_clean(ext) as f: - df1.to_excel(f, engine="openpyxl", sheet_name="poo", index=False) - with ExcelWriter( - f, engine="openpyxl", mode="a", if_sheet_exists="overlay" - ) as writer: - # use startrow+1 because we don't have a header - df2.to_excel( - writer, - index=False, - header=False, - startrow=startrow + 1, - startcol=startcol, - sheet_name="poo", - ) + df1.to_excel(tmp_excel, engine="openpyxl", sheet_name="poo", index=False) + with ExcelWriter( + tmp_excel, engine="openpyxl", mode="a", if_sheet_exists="overlay" + ) as writer: + # use startrow+1 because we don't have a header + df2.to_excel( + writer, + index=False, + header=False, + startrow=startrow + 1, + startcol=startcol, + sheet_name="poo", + ) - result = pd.read_excel(f, sheet_name="poo", engine="openpyxl") - expected = DataFrame({"greeting": greeting, "goodbye": goodbye}) - tm.assert_frame_equal(result, expected) + result = pd.read_excel(tmp_excel, sheet_name="poo", engine="openpyxl") + expected = DataFrame({"greeting": greeting, "goodbye": goodbye}) + tm.assert_frame_equal(result, expected) @pytest.mark.parametrize( @@ -265,29 +273,27 @@ def test_append_overlay_startrow_startcol(ext, startrow, startcol, greeting, goo ), ], ) -def test_if_sheet_exists_raises(ext, if_sheet_exists, msg): +def test_if_sheet_exists_raises(tmp_excel, if_sheet_exists, msg): # GH 40230 df = DataFrame({"fruit": ["pear"]}) - with tm.ensure_clean(ext) as f: - df.to_excel(f, sheet_name="foo", engine="openpyxl") - with pytest.raises(ValueError, match=re.escape(msg)): - with ExcelWriter( - f, engine="openpyxl", mode="a", if_sheet_exists=if_sheet_exists - ) as writer: - df.to_excel(writer, sheet_name="foo") + df.to_excel(tmp_excel, sheet_name="foo", engine="openpyxl") + with pytest.raises(ValueError, match=re.escape(msg)): + with ExcelWriter( + tmp_excel, engine="openpyxl", mode="a", if_sheet_exists=if_sheet_exists + ) as writer: + df.to_excel(writer, sheet_name="foo") -def test_to_excel_with_openpyxl_engine(ext): +def test_to_excel_with_openpyxl_engine(tmp_excel): # GH 29854 - with tm.ensure_clean(ext) as filename: - df1 = DataFrame({"A": np.linspace(1, 10, 10)}) - df2 = DataFrame({"B": np.linspace(1, 20, 10)}) - df = pd.concat([df1, df2], axis=1) - styled = df.style.map( - lambda val: f"color: {'red' if val < 0 else 'black'}" - ).highlight_max() + df1 = DataFrame({"A": np.linspace(1, 10, 10)}) + df2 = DataFrame({"B": np.linspace(1, 20, 10)}) + df = pd.concat([df1, df2], axis=1) + styled = df.style.map( + lambda val: f"color: {'red' if val < 0 else 'black'}" + ).highlight_max() - styled.to_excel(filename, engine="openpyxl") + styled.to_excel(tmp_excel, engine="openpyxl") @pytest.mark.parametrize("read_only", [True, False]) @@ -337,25 +343,24 @@ def test_read_with_bad_dimension( tm.assert_frame_equal(result, expected) -def test_append_mode_file(ext): +def test_append_mode_file(tmp_excel): # GH 39576 df = DataFrame() - with tm.ensure_clean(ext) as f: - df.to_excel(f, engine="openpyxl") + df.to_excel(tmp_excel, engine="openpyxl") - with ExcelWriter( - f, mode="a", engine="openpyxl", if_sheet_exists="new" - ) as writer: - df.to_excel(writer) + with ExcelWriter( + tmp_excel, mode="a", engine="openpyxl", if_sheet_exists="new" + ) as writer: + df.to_excel(writer) - # make sure that zip files are not concatenated by making sure that - # "docProps/app.xml" only occurs twice in the file - data = Path(f).read_bytes() - first = data.find(b"docProps/app.xml") - second = data.find(b"docProps/app.xml", first + 1) - third = data.find(b"docProps/app.xml", second + 1) - assert second != -1 and third == -1 + # make sure that zip files are not concatenated by making sure that + # "docProps/app.xml" only occurs twice in the file + data = Path(tmp_excel).read_bytes() + first = data.find(b"docProps/app.xml") + second = data.find(b"docProps/app.xml", first + 1) + third = data.find(b"docProps/app.xml", second + 1) + assert second != -1 and third == -1 # When read_only is None, use read_excel instead of a workbook @@ -396,13 +401,12 @@ def test_read_empty_with_blank_row(datapath, ext, read_only): tm.assert_frame_equal(result, expected) -def test_book_and_sheets_consistent(ext): +def test_book_and_sheets_consistent(tmp_excel): # GH#45687 - Ensure sheets is updated if user modifies book - with tm.ensure_clean(ext) as f: - with ExcelWriter(f, engine="openpyxl") as writer: - assert writer.sheets == {} - sheet = writer.book.create_sheet("test_name", 0) - assert writer.sheets == {"test_name": sheet} + with ExcelWriter(tmp_excel, engine="openpyxl") as writer: + assert writer.sheets == {} + sheet = writer.book.create_sheet("test_name", 0) + assert writer.sheets == {"test_name": sheet} def test_ints_spelled_with_decimals(datapath, ext): diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index e4a8791396ee2..482b2b7b719e3 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -122,6 +122,14 @@ def read_ext(engine_and_read_ext): return read_ext +@pytest.fixture +def tmp_excel(read_ext, tmp_path): + tmp = tmp_path / f"tmp{read_ext}" + tmp.touch() + yield str(tmp) + tmp.unlink() + + @pytest.fixture def df_ref(datapath): """ @@ -588,7 +596,7 @@ def test_reader_dtype_str(self, read_ext, dtype, expected): expected = DataFrame(expected) tm.assert_frame_equal(actual, expected) - def test_dtype_backend(self, read_ext, dtype_backend, engine): + def test_dtype_backend(self, read_ext, dtype_backend, engine, tmp_excel): # GH#36712 if read_ext in (".xlsb", ".xls"): pytest.skip(f"No engine for filetype: '{read_ext}'") @@ -607,11 +615,10 @@ def test_dtype_backend(self, read_ext, dtype_backend, engine): "j": Series([pd.NA, pd.NA], dtype="Int64"), } ) - with tm.ensure_clean(read_ext) as file_path: - df.to_excel(file_path, sheet_name="test", index=False) - result = pd.read_excel( - file_path, sheet_name="test", dtype_backend=dtype_backend - ) + df.to_excel(tmp_excel, sheet_name="test", index=False) + result = pd.read_excel( + tmp_excel, sheet_name="test", dtype_backend=dtype_backend + ) if dtype_backend == "pyarrow": import pyarrow as pa @@ -636,26 +643,25 @@ def test_dtype_backend(self, read_ext, dtype_backend, engine): tm.assert_frame_equal(result, expected) - def test_dtype_backend_and_dtype(self, read_ext): + def test_dtype_backend_and_dtype(self, read_ext, tmp_excel): # GH#36712 if read_ext in (".xlsb", ".xls"): pytest.skip(f"No engine for filetype: '{read_ext}'") df = DataFrame({"a": [np.nan, 1.0], "b": [2.5, np.nan]}) - with tm.ensure_clean(read_ext) as file_path: - df.to_excel(file_path, sheet_name="test", index=False) - result = pd.read_excel( - file_path, - sheet_name="test", - dtype_backend="numpy_nullable", - dtype="float64", - ) + df.to_excel(tmp_excel, sheet_name="test", index=False) + result = pd.read_excel( + tmp_excel, + sheet_name="test", + dtype_backend="numpy_nullable", + dtype="float64", + ) tm.assert_frame_equal(result, df) @pytest.mark.xfail( using_pyarrow_string_dtype(), reason="infer_string takes precedence" ) - def test_dtype_backend_string(self, read_ext, string_storage): + def test_dtype_backend_string(self, read_ext, string_storage, tmp_excel): # GH#36712 if read_ext in (".xlsb", ".xls"): pytest.skip(f"No engine for filetype: '{read_ext}'") @@ -669,11 +675,10 @@ def test_dtype_backend_string(self, read_ext, string_storage): "b": np.array(["x", pd.NA], dtype=np.object_), } ) - with tm.ensure_clean(read_ext) as file_path: - df.to_excel(file_path, sheet_name="test", index=False) - result = pd.read_excel( - file_path, sheet_name="test", dtype_backend="numpy_nullable" - ) + df.to_excel(tmp_excel, sheet_name="test", index=False) + result = pd.read_excel( + tmp_excel, sheet_name="test", dtype_backend="numpy_nullable" + ) if string_storage == "python": expected = DataFrame( @@ -1701,7 +1706,7 @@ def test_ignore_chartsheets(self, request, engine, read_ext): with pd.ExcelFile("chartsheet" + read_ext) as excel: assert excel.sheet_names == ["Sheet1"] - def test_corrupt_files_closed(self, engine, read_ext): + def test_corrupt_files_closed(self, engine, tmp_excel): # GH41778 errors = (BadZipFile,) if engine is None: @@ -1715,10 +1720,9 @@ def test_corrupt_files_closed(self, engine, read_ext): errors = (CalamineError,) - with tm.ensure_clean(f"corrupt{read_ext}") as file: - Path(file).write_text("corrupt", encoding="utf-8") - with tm.assert_produces_warning(False): - try: - pd.ExcelFile(file, engine=engine) - except errors: - pass + Path(tmp_excel).write_text("corrupt", encoding="utf-8") + with tm.assert_produces_warning(False): + try: + pd.ExcelFile(tmp_excel, engine=engine) + except errors: + pass diff --git a/pandas/tests/io/excel/test_style.py b/pandas/tests/io/excel/test_style.py index 58b297e4520bb..b50e6291d92e9 100644 --- a/pandas/tests/io/excel/test_style.py +++ b/pandas/tests/io/excel/test_style.py @@ -21,6 +21,14 @@ # 'template' file, but this needs the import error to delayed until render time. +@pytest.fixture +def tmp_excel(tmp_path): + tmp = tmp_path / "tmp.xlsx" + tmp.touch() + yield str(tmp) + tmp.unlink() + + def assert_equal_cell_styles(cell1, cell2): # TODO: should find a better way to check equality assert cell1.alignment.__dict__ == cell2.alignment.__dict__ @@ -31,48 +39,43 @@ def assert_equal_cell_styles(cell1, cell2): assert cell1.protection.__dict__ == cell2.protection.__dict__ -def test_styler_default_values(): +def test_styler_default_values(tmp_excel): # GH 54154 openpyxl = pytest.importorskip("openpyxl") df = DataFrame([{"A": 1, "B": 2, "C": 3}, {"A": 1, "B": 2, "C": 3}]) - with tm.ensure_clean(".xlsx") as path: - with ExcelWriter(path, engine="openpyxl") as writer: - df.to_excel(writer, sheet_name="custom") + with ExcelWriter(tmp_excel, engine="openpyxl") as writer: + df.to_excel(writer, sheet_name="custom") - with contextlib.closing(openpyxl.load_workbook(path)) as wb: - # Check font, spacing, indentation - assert wb["custom"].cell(1, 1).font.bold is False - assert wb["custom"].cell(1, 1).alignment.horizontal is None - assert wb["custom"].cell(1, 1).alignment.vertical is None + with contextlib.closing(openpyxl.load_workbook(tmp_excel)) as wb: + # Check font, spacing, indentation + assert wb["custom"].cell(1, 1).font.bold is False + assert wb["custom"].cell(1, 1).alignment.horizontal is None + assert wb["custom"].cell(1, 1).alignment.vertical is None - # Check border - assert wb["custom"].cell(1, 1).border.bottom.color is None - assert wb["custom"].cell(1, 1).border.top.color is None - assert wb["custom"].cell(1, 1).border.left.color is None - assert wb["custom"].cell(1, 1).border.right.color is None + # Check border + assert wb["custom"].cell(1, 1).border.bottom.color is None + assert wb["custom"].cell(1, 1).border.top.color is None + assert wb["custom"].cell(1, 1).border.left.color is None + assert wb["custom"].cell(1, 1).border.right.color is None -@pytest.mark.parametrize( - "engine", - ["xlsxwriter", "openpyxl"], -) -def test_styler_to_excel_unstyled(engine): +@pytest.mark.parametrize("engine", ["xlsxwriter", "openpyxl"]) +def test_styler_to_excel_unstyled(engine, tmp_excel): # compare DataFrame.to_excel and Styler.to_excel when no styles applied pytest.importorskip(engine) df = DataFrame(np.random.default_rng(2).standard_normal((2, 2))) - with tm.ensure_clean(".xlsx") as path: - with ExcelWriter(path, engine=engine) as writer: - df.to_excel(writer, sheet_name="dataframe") - df.style.to_excel(writer, sheet_name="unstyled") + with ExcelWriter(tmp_excel, engine=engine) as writer: + df.to_excel(writer, sheet_name="dataframe") + df.style.to_excel(writer, sheet_name="unstyled") - openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl - with contextlib.closing(openpyxl.load_workbook(path)) as wb: - for col1, col2 in zip(wb["dataframe"].columns, wb["unstyled"].columns): - assert len(col1) == len(col2) - for cell1, cell2 in zip(col1, col2): - assert cell1.value == cell2.value - assert_equal_cell_styles(cell1, cell2) + openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl + with contextlib.closing(openpyxl.load_workbook(tmp_excel)) as wb: + for col1, col2 in zip(wb["dataframe"].columns, wb["unstyled"].columns): + assert len(col1) == len(col2) + for cell1, cell2 in zip(col1, col2): + assert cell1.value == cell2.value + assert_equal_cell_styles(cell1, cell2) shared_style_params = [ @@ -145,73 +148,65 @@ def test_styler_to_excel_unstyled(engine): ] -def test_styler_custom_style(): +def test_styler_custom_style(tmp_excel): # GH 54154 css_style = "background-color: #111222" openpyxl = pytest.importorskip("openpyxl") df = DataFrame([{"A": 1, "B": 2}, {"A": 1, "B": 2}]) - with tm.ensure_clean(".xlsx") as path: - with ExcelWriter(path, engine="openpyxl") as writer: - styler = df.style.map(lambda x: css_style) - styler.to_excel(writer, sheet_name="custom", index=False) - - with contextlib.closing(openpyxl.load_workbook(path)) as wb: - # Check font, spacing, indentation - assert wb["custom"].cell(1, 1).font.bold is False - assert wb["custom"].cell(1, 1).alignment.horizontal is None - assert wb["custom"].cell(1, 1).alignment.vertical is None - - # Check border - assert wb["custom"].cell(1, 1).border.bottom.color is None - assert wb["custom"].cell(1, 1).border.top.color is None - assert wb["custom"].cell(1, 1).border.left.color is None - assert wb["custom"].cell(1, 1).border.right.color is None - - # Check background color - assert wb["custom"].cell(2, 1).fill.fgColor.index == "00111222" - assert wb["custom"].cell(3, 1).fill.fgColor.index == "00111222" - assert wb["custom"].cell(2, 2).fill.fgColor.index == "00111222" - assert wb["custom"].cell(3, 2).fill.fgColor.index == "00111222" - - -@pytest.mark.parametrize( - "engine", - ["xlsxwriter", "openpyxl"], -) + with ExcelWriter(tmp_excel, engine="openpyxl") as writer: + styler = df.style.map(lambda x: css_style) + styler.to_excel(writer, sheet_name="custom", index=False) + + with contextlib.closing(openpyxl.load_workbook(tmp_excel)) as wb: + # Check font, spacing, indentation + assert wb["custom"].cell(1, 1).font.bold is False + assert wb["custom"].cell(1, 1).alignment.horizontal is None + assert wb["custom"].cell(1, 1).alignment.vertical is None + + # Check border + assert wb["custom"].cell(1, 1).border.bottom.color is None + assert wb["custom"].cell(1, 1).border.top.color is None + assert wb["custom"].cell(1, 1).border.left.color is None + assert wb["custom"].cell(1, 1).border.right.color is None + + # Check background color + assert wb["custom"].cell(2, 1).fill.fgColor.index == "00111222" + assert wb["custom"].cell(3, 1).fill.fgColor.index == "00111222" + assert wb["custom"].cell(2, 2).fill.fgColor.index == "00111222" + assert wb["custom"].cell(3, 2).fill.fgColor.index == "00111222" + + +@pytest.mark.parametrize("engine", ["xlsxwriter", "openpyxl"]) @pytest.mark.parametrize("css, attrs, expected", shared_style_params) -def test_styler_to_excel_basic(engine, css, attrs, expected): +def test_styler_to_excel_basic(engine, css, attrs, expected, tmp_excel): pytest.importorskip(engine) df = DataFrame(np.random.default_rng(2).standard_normal((1, 1))) styler = df.style.map(lambda x: css) - with tm.ensure_clean(".xlsx") as path: - with ExcelWriter(path, engine=engine) as writer: - df.to_excel(writer, sheet_name="dataframe") - styler.to_excel(writer, sheet_name="styled") - - openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl - with contextlib.closing(openpyxl.load_workbook(path)) as wb: - # test unstyled data cell does not have expected styles - # test styled cell has expected styles - u_cell, s_cell = wb["dataframe"].cell(2, 2), wb["styled"].cell(2, 2) - for attr in attrs: - u_cell, s_cell = getattr(u_cell, attr, None), getattr(s_cell, attr) - - if isinstance(expected, dict): - assert u_cell is None or u_cell != expected[engine] - assert s_cell == expected[engine] - else: - assert u_cell is None or u_cell != expected - assert s_cell == expected - - -@pytest.mark.parametrize( - "engine", - ["xlsxwriter", "openpyxl"], -) + with ExcelWriter(tmp_excel, engine=engine) as writer: + df.to_excel(writer, sheet_name="dataframe") + styler.to_excel(writer, sheet_name="styled") + + openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl + with contextlib.closing(openpyxl.load_workbook(tmp_excel)) as wb: + # test unstyled data cell does not have expected styles + # test styled cell has expected styles + u_cell, s_cell = wb["dataframe"].cell(2, 2), wb["styled"].cell(2, 2) + for attr in attrs: + u_cell, s_cell = getattr(u_cell, attr, None), getattr(s_cell, attr) + + if isinstance(expected, dict): + assert u_cell is None or u_cell != expected[engine] + assert s_cell == expected[engine] + else: + assert u_cell is None or u_cell != expected + assert s_cell == expected + + +@pytest.mark.parametrize("engine", ["xlsxwriter", "openpyxl"]) @pytest.mark.parametrize("css, attrs, expected", shared_style_params) -def test_styler_to_excel_basic_indexes(engine, css, attrs, expected): +def test_styler_to_excel_basic_indexes(engine, css, attrs, expected, tmp_excel): pytest.importorskip(engine) df = DataFrame(np.random.default_rng(2).standard_normal((1, 1))) @@ -224,31 +219,30 @@ def test_styler_to_excel_basic_indexes(engine, css, attrs, expected): null_styler.map_index(lambda x: "null: css;", axis=0) null_styler.map_index(lambda x: "null: css;", axis=1) - with tm.ensure_clean(".xlsx") as path: - with ExcelWriter(path, engine=engine) as writer: - null_styler.to_excel(writer, sheet_name="null_styled") - styler.to_excel(writer, sheet_name="styled") - - openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl - with contextlib.closing(openpyxl.load_workbook(path)) as wb: - # test null styled index cells does not have expected styles - # test styled cell has expected styles - ui_cell, si_cell = wb["null_styled"].cell(2, 1), wb["styled"].cell(2, 1) - uc_cell, sc_cell = wb["null_styled"].cell(1, 2), wb["styled"].cell(1, 2) - for attr in attrs: - ui_cell, si_cell = getattr(ui_cell, attr, None), getattr(si_cell, attr) - uc_cell, sc_cell = getattr(uc_cell, attr, None), getattr(sc_cell, attr) - - if isinstance(expected, dict): - assert ui_cell is None or ui_cell != expected[engine] - assert si_cell == expected[engine] - assert uc_cell is None or uc_cell != expected[engine] - assert sc_cell == expected[engine] - else: - assert ui_cell is None or ui_cell != expected - assert si_cell == expected - assert uc_cell is None or uc_cell != expected - assert sc_cell == expected + with ExcelWriter(tmp_excel, engine=engine) as writer: + null_styler.to_excel(writer, sheet_name="null_styled") + styler.to_excel(writer, sheet_name="styled") + + openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl + with contextlib.closing(openpyxl.load_workbook(tmp_excel)) as wb: + # test null styled index cells does not have expected styles + # test styled cell has expected styles + ui_cell, si_cell = wb["null_styled"].cell(2, 1), wb["styled"].cell(2, 1) + uc_cell, sc_cell = wb["null_styled"].cell(1, 2), wb["styled"].cell(1, 2) + for attr in attrs: + ui_cell, si_cell = getattr(ui_cell, attr, None), getattr(si_cell, attr) + uc_cell, sc_cell = getattr(uc_cell, attr, None), getattr(sc_cell, attr) + + if isinstance(expected, dict): + assert ui_cell is None or ui_cell != expected[engine] + assert si_cell == expected[engine] + assert uc_cell is None or uc_cell != expected[engine] + assert sc_cell == expected[engine] + else: + assert ui_cell is None or ui_cell != expected + assert si_cell == expected + assert uc_cell is None or uc_cell != expected + assert sc_cell == expected # From https://openpyxl.readthedocs.io/en/stable/api/openpyxl.styles.borders.html @@ -271,12 +265,9 @@ def test_styler_to_excel_basic_indexes(engine, css, attrs, expected): ] -@pytest.mark.parametrize( - "engine", - ["xlsxwriter", "openpyxl"], -) +@pytest.mark.parametrize("engine", ["xlsxwriter", "openpyxl"]) @pytest.mark.parametrize("border_style", excel_border_styles) -def test_styler_to_excel_border_style(engine, border_style): +def test_styler_to_excel_border_style(engine, border_style, tmp_excel): css = f"border-left: {border_style} black thin" attrs = ["border", "left", "style"] expected = border_style @@ -285,28 +276,27 @@ def test_styler_to_excel_border_style(engine, border_style): df = DataFrame(np.random.default_rng(2).standard_normal((1, 1))) styler = df.style.map(lambda x: css) - with tm.ensure_clean(".xlsx") as path: - with ExcelWriter(path, engine=engine) as writer: - df.to_excel(writer, sheet_name="dataframe") - styler.to_excel(writer, sheet_name="styled") + with ExcelWriter(tmp_excel, engine=engine) as writer: + df.to_excel(writer, sheet_name="dataframe") + styler.to_excel(writer, sheet_name="styled") - openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl - with contextlib.closing(openpyxl.load_workbook(path)) as wb: - # test unstyled data cell does not have expected styles - # test styled cell has expected styles - u_cell, s_cell = wb["dataframe"].cell(2, 2), wb["styled"].cell(2, 2) - for attr in attrs: - u_cell, s_cell = getattr(u_cell, attr, None), getattr(s_cell, attr) + openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl + with contextlib.closing(openpyxl.load_workbook(tmp_excel)) as wb: + # test unstyled data cell does not have expected styles + # test styled cell has expected styles + u_cell, s_cell = wb["dataframe"].cell(2, 2), wb["styled"].cell(2, 2) + for attr in attrs: + u_cell, s_cell = getattr(u_cell, attr, None), getattr(s_cell, attr) - if isinstance(expected, dict): - assert u_cell is None or u_cell != expected[engine] - assert s_cell == expected[engine] - else: - assert u_cell is None or u_cell != expected - assert s_cell == expected + if isinstance(expected, dict): + assert u_cell is None or u_cell != expected[engine] + assert s_cell == expected[engine] + else: + assert u_cell is None or u_cell != expected + assert s_cell == expected -def test_styler_custom_converter(): +def test_styler_custom_converter(tmp_excel): openpyxl = pytest.importorskip("openpyxl") def custom_converter(css): @@ -314,14 +304,13 @@ def custom_converter(css): df = DataFrame(np.random.default_rng(2).standard_normal((1, 1))) styler = df.style.map(lambda x: "color: #888999") - with tm.ensure_clean(".xlsx") as path: - with ExcelWriter(path, engine="openpyxl") as writer: - ExcelFormatter(styler, style_converter=custom_converter).write( - writer, sheet_name="custom" - ) - - with contextlib.closing(openpyxl.load_workbook(path)) as wb: - assert wb["custom"].cell(2, 2).font.color.value == "00111222" + with ExcelWriter(tmp_excel, engine="openpyxl") as writer: + ExcelFormatter(styler, style_converter=custom_converter).write( + writer, sheet_name="custom" + ) + + with contextlib.closing(openpyxl.load_workbook(tmp_excel)) as wb: + assert wb["custom"].cell(2, 2).font.color.value == "00111222" @pytest.mark.single_cpu diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 3352164b2f980..48142a91079b5 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -53,12 +53,14 @@ def merge_cells(request): @pytest.fixture -def path(ext): +def tmp_excel(ext, tmp_path): """ Fixture to open file for use in each test case. """ - with tm.ensure_clean(ext) as file_path: - yield file_path + tmp = tmp_path / f"tmp{ext}" + tmp.touch() + yield str(tmp) + tmp.unlink() @pytest.fixture @@ -92,16 +94,15 @@ class TestRoundTrip: "header,expected", [(None, [np.nan] * 4), (0, {"Unnamed: 0": [np.nan] * 3})], ) - def test_read_one_empty_col_no_header(self, ext, header, expected): + def test_read_one_empty_col_no_header(self, tmp_excel, header, expected): # xref gh-12292 filename = "no_header" df = DataFrame([["", 1, 100], ["", 2, 200], ["", 3, 300], ["", 4, 400]]) - with tm.ensure_clean(ext) as path: - df.to_excel(path, sheet_name=filename, index=False, header=False) - result = pd.read_excel( - path, sheet_name=filename, usecols=[0], header=header - ) + df.to_excel(tmp_excel, sheet_name=filename, index=False, header=False) + result = pd.read_excel( + tmp_excel, sheet_name=filename, usecols=[0], header=header + ) expected = DataFrame(expected) tm.assert_frame_equal(result, expected) @@ -109,47 +110,43 @@ def test_read_one_empty_col_no_header(self, ext, header, expected): "header,expected_extra", [(None, [0]), (0, [])], ) - def test_read_one_empty_col_with_header(self, ext, header, expected_extra): + def test_read_one_empty_col_with_header(self, tmp_excel, header, expected_extra): filename = "with_header" df = DataFrame([["", 1, 100], ["", 2, 200], ["", 3, 300], ["", 4, 400]]) - with tm.ensure_clean(ext) as path: - df.to_excel(path, sheet_name="with_header", index=False, header=True) - result = pd.read_excel( - path, sheet_name=filename, usecols=[0], header=header - ) + df.to_excel(tmp_excel, sheet_name="with_header", index=False, header=True) + result = pd.read_excel( + tmp_excel, sheet_name=filename, usecols=[0], header=header + ) expected = DataFrame(expected_extra + [np.nan] * 4) tm.assert_frame_equal(result, expected) - def test_set_column_names_in_parameter(self, ext): + def test_set_column_names_in_parameter(self, tmp_excel): # GH 12870 : pass down column names associated with # keyword argument names refdf = DataFrame([[1, "foo"], [2, "bar"], [3, "baz"]], columns=["a", "b"]) - with tm.ensure_clean(ext) as pth: - with ExcelWriter(pth) as writer: - refdf.to_excel( - writer, sheet_name="Data_no_head", header=False, index=False - ) - refdf.to_excel(writer, sheet_name="Data_with_head", index=False) + with ExcelWriter(tmp_excel) as writer: + refdf.to_excel(writer, sheet_name="Data_no_head", header=False, index=False) + refdf.to_excel(writer, sheet_name="Data_with_head", index=False) - refdf.columns = ["A", "B"] + refdf.columns = ["A", "B"] - with ExcelFile(pth) as reader: - xlsdf_no_head = pd.read_excel( - reader, sheet_name="Data_no_head", header=None, names=["A", "B"] - ) - xlsdf_with_head = pd.read_excel( - reader, - sheet_name="Data_with_head", - index_col=None, - names=["A", "B"], - ) + with ExcelFile(tmp_excel) as reader: + xlsdf_no_head = pd.read_excel( + reader, sheet_name="Data_no_head", header=None, names=["A", "B"] + ) + xlsdf_with_head = pd.read_excel( + reader, + sheet_name="Data_with_head", + index_col=None, + names=["A", "B"], + ) - tm.assert_frame_equal(xlsdf_no_head, refdf) - tm.assert_frame_equal(xlsdf_with_head, refdf) + tm.assert_frame_equal(xlsdf_no_head, refdf) + tm.assert_frame_equal(xlsdf_with_head, refdf) - def test_creating_and_reading_multiple_sheets(self, ext): + def test_creating_and_reading_multiple_sheets(self, tmp_excel): # see gh-9450 # # Test reading multiple sheets, from a runtime @@ -163,124 +160,126 @@ def tdf(col_sheet_name): dfs = [tdf(s) for s in sheets] dfs = dict(zip(sheets, dfs)) - with tm.ensure_clean(ext) as pth: - with ExcelWriter(pth) as ew: - for sheetname, df in dfs.items(): - df.to_excel(ew, sheet_name=sheetname) + with ExcelWriter(tmp_excel) as ew: + for sheetname, df in dfs.items(): + df.to_excel(ew, sheet_name=sheetname) - dfs_returned = pd.read_excel(pth, sheet_name=sheets, index_col=0) + dfs_returned = pd.read_excel(tmp_excel, sheet_name=sheets, index_col=0) - for s in sheets: - tm.assert_frame_equal(dfs[s], dfs_returned[s]) + for s in sheets: + tm.assert_frame_equal(dfs[s], dfs_returned[s]) - def test_read_excel_multiindex_empty_level(self, ext): + def test_read_excel_multiindex_empty_level(self, tmp_excel): # see gh-12453 - with tm.ensure_clean(ext) as path: - df = DataFrame( - { - ("One", "x"): {0: 1}, - ("Two", "X"): {0: 3}, - ("Two", "Y"): {0: 7}, - ("Zero", ""): {0: 0}, - } - ) + df = DataFrame( + { + ("One", "x"): {0: 1}, + ("Two", "X"): {0: 3}, + ("Two", "Y"): {0: 7}, + ("Zero", ""): {0: 0}, + } + ) - expected = DataFrame( - { - ("One", "x"): {0: 1}, - ("Two", "X"): {0: 3}, - ("Two", "Y"): {0: 7}, - ("Zero", "Unnamed: 4_level_1"): {0: 0}, - } - ) + expected = DataFrame( + { + ("One", "x"): {0: 1}, + ("Two", "X"): {0: 3}, + ("Two", "Y"): {0: 7}, + ("Zero", "Unnamed: 4_level_1"): {0: 0}, + } + ) - df.to_excel(path) - actual = pd.read_excel(path, header=[0, 1], index_col=0) - tm.assert_frame_equal(actual, expected) + df.to_excel(tmp_excel) + actual = pd.read_excel(tmp_excel, header=[0, 1], index_col=0) + tm.assert_frame_equal(actual, expected) - df = DataFrame( - { - ("Beg", ""): {0: 0}, - ("Middle", "x"): {0: 1}, - ("Tail", "X"): {0: 3}, - ("Tail", "Y"): {0: 7}, - } - ) + df = DataFrame( + { + ("Beg", ""): {0: 0}, + ("Middle", "x"): {0: 1}, + ("Tail", "X"): {0: 3}, + ("Tail", "Y"): {0: 7}, + } + ) - expected = DataFrame( - { - ("Beg", "Unnamed: 1_level_1"): {0: 0}, - ("Middle", "x"): {0: 1}, - ("Tail", "X"): {0: 3}, - ("Tail", "Y"): {0: 7}, - } - ) + expected = DataFrame( + { + ("Beg", "Unnamed: 1_level_1"): {0: 0}, + ("Middle", "x"): {0: 1}, + ("Tail", "X"): {0: 3}, + ("Tail", "Y"): {0: 7}, + } + ) - df.to_excel(path) - actual = pd.read_excel(path, header=[0, 1], index_col=0) - tm.assert_frame_equal(actual, expected) + df.to_excel(tmp_excel) + actual = pd.read_excel(tmp_excel, header=[0, 1], index_col=0) + tm.assert_frame_equal(actual, expected) @pytest.mark.parametrize("c_idx_names", ["a", None]) @pytest.mark.parametrize("r_idx_names", ["b", None]) @pytest.mark.parametrize("c_idx_levels", [1, 3]) @pytest.mark.parametrize("r_idx_levels", [1, 3]) def test_excel_multindex_roundtrip( - self, ext, c_idx_names, r_idx_names, c_idx_levels, r_idx_levels, request + self, + tmp_excel, + c_idx_names, + r_idx_names, + c_idx_levels, + r_idx_levels, ): # see gh-4679 - with tm.ensure_clean(ext) as pth: - # Empty name case current read in as - # unnamed levels, not Nones. - check_names = bool(r_idx_names) or r_idx_levels <= 1 + # Empty name case current read in as + # unnamed levels, not Nones. + check_names = bool(r_idx_names) or r_idx_levels <= 1 - if c_idx_levels == 1: - columns = Index(list("abcde")) - else: - columns = MultiIndex.from_arrays( - [range(5) for _ in range(c_idx_levels)], - names=[f"{c_idx_names}-{i}" for i in range(c_idx_levels)], - ) - if r_idx_levels == 1: - index = Index(list("ghijk")) - else: - index = MultiIndex.from_arrays( - [range(5) for _ in range(r_idx_levels)], - names=[f"{r_idx_names}-{i}" for i in range(r_idx_levels)], - ) - df = DataFrame( - 1.1 * np.ones((5, 5)), - columns=columns, - index=index, + if c_idx_levels == 1: + columns = Index(list("abcde")) + else: + columns = MultiIndex.from_arrays( + [range(5) for _ in range(c_idx_levels)], + names=[f"{c_idx_names}-{i}" for i in range(c_idx_levels)], ) - df.to_excel(pth) - - act = pd.read_excel( - pth, - index_col=list(range(r_idx_levels)), - header=list(range(c_idx_levels)), + if r_idx_levels == 1: + index = Index(list("ghijk")) + else: + index = MultiIndex.from_arrays( + [range(5) for _ in range(r_idx_levels)], + names=[f"{r_idx_names}-{i}" for i in range(r_idx_levels)], ) - tm.assert_frame_equal(df, act, check_names=check_names) + df = DataFrame( + 1.1 * np.ones((5, 5)), + columns=columns, + index=index, + ) + df.to_excel(tmp_excel) - df.iloc[0, :] = np.nan - df.to_excel(pth) + act = pd.read_excel( + tmp_excel, + index_col=list(range(r_idx_levels)), + header=list(range(c_idx_levels)), + ) + tm.assert_frame_equal(df, act, check_names=check_names) - act = pd.read_excel( - pth, - index_col=list(range(r_idx_levels)), - header=list(range(c_idx_levels)), - ) - tm.assert_frame_equal(df, act, check_names=check_names) - - df.iloc[-1, :] = np.nan - df.to_excel(pth) - act = pd.read_excel( - pth, - index_col=list(range(r_idx_levels)), - header=list(range(c_idx_levels)), - ) - tm.assert_frame_equal(df, act, check_names=check_names) + df.iloc[0, :] = np.nan + df.to_excel(tmp_excel) + + act = pd.read_excel( + tmp_excel, + index_col=list(range(r_idx_levels)), + header=list(range(c_idx_levels)), + ) + tm.assert_frame_equal(df, act, check_names=check_names) + + df.iloc[-1, :] = np.nan + df.to_excel(tmp_excel) + act = pd.read_excel( + tmp_excel, + index_col=list(range(r_idx_levels)), + header=list(range(c_idx_levels)), + ) + tm.assert_frame_equal(df, act, check_names=check_names) - def test_read_excel_parse_dates(self, ext): + def test_read_excel_parse_dates(self, tmp_excel): # see gh-11544, gh-12051 df = DataFrame( {"col": [1, 2, 3], "date_strings": date_range("2012-01-01", periods=3)} @@ -288,34 +287,33 @@ def test_read_excel_parse_dates(self, ext): df2 = df.copy() df2["date_strings"] = df2["date_strings"].dt.strftime("%m/%d/%Y") - with tm.ensure_clean(ext) as pth: - df2.to_excel(pth) + df2.to_excel(tmp_excel) - res = pd.read_excel(pth, index_col=0) - tm.assert_frame_equal(df2, res) + res = pd.read_excel(tmp_excel, index_col=0) + tm.assert_frame_equal(df2, res) - res = pd.read_excel(pth, parse_dates=["date_strings"], index_col=0) - tm.assert_frame_equal(df, res) + res = pd.read_excel(tmp_excel, parse_dates=["date_strings"], index_col=0) + tm.assert_frame_equal(df, res) - date_parser = lambda x: datetime.strptime(x, "%m/%d/%Y") - with tm.assert_produces_warning( - FutureWarning, - match="use 'date_format' instead", - raise_on_extra_warnings=False, - ): - res = pd.read_excel( - pth, - parse_dates=["date_strings"], - date_parser=date_parser, - index_col=0, - ) - tm.assert_frame_equal(df, res) + date_parser = lambda x: datetime.strptime(x, "%m/%d/%Y") + with tm.assert_produces_warning( + FutureWarning, + match="use 'date_format' instead", + raise_on_extra_warnings=False, + ): res = pd.read_excel( - pth, parse_dates=["date_strings"], date_format="%m/%d/%Y", index_col=0 + tmp_excel, + parse_dates=["date_strings"], + date_parser=date_parser, + index_col=0, ) - tm.assert_frame_equal(df, res) + tm.assert_frame_equal(df, res) + res = pd.read_excel( + tmp_excel, parse_dates=["date_strings"], date_format="%m/%d/%Y", index_col=0 + ) + tm.assert_frame_equal(df, res) - def test_multiindex_interval_datetimes(self, ext): + def test_multiindex_interval_datetimes(self, tmp_excel): # GH 30986 midx = MultiIndex.from_arrays( [ @@ -326,9 +324,8 @@ def test_multiindex_interval_datetimes(self, ext): ] ) df = DataFrame(range(4), index=midx) - with tm.ensure_clean(ext) as pth: - df.to_excel(pth) - result = pd.read_excel(pth, index_col=[0, 1]) + df.to_excel(tmp_excel) + result = pd.read_excel(tmp_excel, index_col=[0, 1]) expected = DataFrame( range(4), MultiIndex.from_arrays( @@ -369,7 +366,7 @@ def test_multiindex_interval_datetimes(self, ext): ) @pytest.mark.usefixtures("set_engine") class TestExcelWriter: - def test_excel_sheet_size(self, path): + def test_excel_sheet_size(self, tmp_excel): # GH 26080 breaking_row_count = 2**20 + 1 breaking_col_count = 2**14 + 1 @@ -381,16 +378,16 @@ def test_excel_sheet_size(self, path): msg = "sheet is too large" with pytest.raises(ValueError, match=msg): - row_df.to_excel(path) + row_df.to_excel(tmp_excel) with pytest.raises(ValueError, match=msg): - col_df.to_excel(path) + col_df.to_excel(tmp_excel) - def test_excel_sheet_by_name_raise(self, path): + def test_excel_sheet_by_name_raise(self, tmp_excel): gt = DataFrame(np.random.default_rng(2).standard_normal((10, 2))) - gt.to_excel(path) + gt.to_excel(tmp_excel) - with ExcelFile(path) as xl: + with ExcelFile(tmp_excel) as xl: df = pd.read_excel(xl, sheet_name=0, index_col=0) tm.assert_frame_equal(gt, df) @@ -399,80 +396,84 @@ def test_excel_sheet_by_name_raise(self, path): with pytest.raises(ValueError, match=msg): pd.read_excel(xl, "0") - def test_excel_writer_context_manager(self, frame, path): - with ExcelWriter(path) as writer: + def test_excel_writer_context_manager(self, frame, tmp_excel): + with ExcelWriter(tmp_excel) as writer: frame.to_excel(writer, sheet_name="Data1") frame2 = frame.copy() frame2.columns = frame.columns[::-1] frame2.to_excel(writer, sheet_name="Data2") - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: found_df = pd.read_excel(reader, sheet_name="Data1", index_col=0) found_df2 = pd.read_excel(reader, sheet_name="Data2", index_col=0) tm.assert_frame_equal(found_df, frame) tm.assert_frame_equal(found_df2, frame2) - def test_roundtrip(self, frame, path): + def test_roundtrip(self, frame, tmp_excel): frame = frame.copy() frame.iloc[:5, frame.columns.get_loc("A")] = np.nan - frame.to_excel(path, sheet_name="test1") - frame.to_excel(path, sheet_name="test1", columns=["A", "B"]) - frame.to_excel(path, sheet_name="test1", header=False) - frame.to_excel(path, sheet_name="test1", index=False) + frame.to_excel(tmp_excel, sheet_name="test1") + frame.to_excel(tmp_excel, sheet_name="test1", columns=["A", "B"]) + frame.to_excel(tmp_excel, sheet_name="test1", header=False) + frame.to_excel(tmp_excel, sheet_name="test1", index=False) # test roundtrip - frame.to_excel(path, sheet_name="test1") - recons = pd.read_excel(path, sheet_name="test1", index_col=0) + frame.to_excel(tmp_excel, sheet_name="test1") + recons = pd.read_excel(tmp_excel, sheet_name="test1", index_col=0) tm.assert_frame_equal(frame, recons) - frame.to_excel(path, sheet_name="test1", index=False) - recons = pd.read_excel(path, sheet_name="test1", index_col=None) + frame.to_excel(tmp_excel, sheet_name="test1", index=False) + recons = pd.read_excel(tmp_excel, sheet_name="test1", index_col=None) recons.index = frame.index tm.assert_frame_equal(frame, recons) - frame.to_excel(path, sheet_name="test1", na_rep="NA") - recons = pd.read_excel(path, sheet_name="test1", index_col=0, na_values=["NA"]) + frame.to_excel(tmp_excel, sheet_name="test1", na_rep="NA") + recons = pd.read_excel( + tmp_excel, sheet_name="test1", index_col=0, na_values=["NA"] + ) tm.assert_frame_equal(frame, recons) # GH 3611 - frame.to_excel(path, sheet_name="test1", na_rep="88") - recons = pd.read_excel(path, sheet_name="test1", index_col=0, na_values=["88"]) + frame.to_excel(tmp_excel, sheet_name="test1", na_rep="88") + recons = pd.read_excel( + tmp_excel, sheet_name="test1", index_col=0, na_values=["88"] + ) tm.assert_frame_equal(frame, recons) - frame.to_excel(path, sheet_name="test1", na_rep="88") + frame.to_excel(tmp_excel, sheet_name="test1", na_rep="88") recons = pd.read_excel( - path, sheet_name="test1", index_col=0, na_values=[88, 88.0] + tmp_excel, sheet_name="test1", index_col=0, na_values=[88, 88.0] ) tm.assert_frame_equal(frame, recons) # GH 6573 - frame.to_excel(path, sheet_name="Sheet1") - recons = pd.read_excel(path, index_col=0) + frame.to_excel(tmp_excel, sheet_name="Sheet1") + recons = pd.read_excel(tmp_excel, index_col=0) tm.assert_frame_equal(frame, recons) - frame.to_excel(path, sheet_name="0") - recons = pd.read_excel(path, index_col=0) + frame.to_excel(tmp_excel, sheet_name="0") + recons = pd.read_excel(tmp_excel, index_col=0) tm.assert_frame_equal(frame, recons) # GH 8825 Pandas Series should provide to_excel method s = frame["A"] - s.to_excel(path) - recons = pd.read_excel(path, index_col=0) + s.to_excel(tmp_excel) + recons = pd.read_excel(tmp_excel, index_col=0) tm.assert_frame_equal(s.to_frame(), recons) - def test_mixed(self, frame, path): + def test_mixed(self, frame, tmp_excel): mixed_frame = frame.copy() mixed_frame["foo"] = "bar" - mixed_frame.to_excel(path, sheet_name="test1") - with ExcelFile(path) as reader: + mixed_frame.to_excel(tmp_excel, sheet_name="test1") + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(mixed_frame, recons) - def test_ts_frame(self, path): - unit = get_exp_unit(path) + def test_ts_frame(self, tmp_excel): + unit = get_exp_unit(tmp_excel) df = DataFrame( np.random.default_rng(2).standard_normal((5, 4)), columns=Index(list("ABCD")), @@ -486,74 +487,74 @@ def test_ts_frame(self, path): expected = df[:] expected.index = expected.index.as_unit(unit) - df.to_excel(path, sheet_name="test1") - with ExcelFile(path) as reader: + df.to_excel(tmp_excel, sheet_name="test1") + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(expected, recons) - def test_basics_with_nan(self, frame, path): + def test_basics_with_nan(self, frame, tmp_excel): frame = frame.copy() frame.iloc[:5, frame.columns.get_loc("A")] = np.nan - frame.to_excel(path, sheet_name="test1") - frame.to_excel(path, sheet_name="test1", columns=["A", "B"]) - frame.to_excel(path, sheet_name="test1", header=False) - frame.to_excel(path, sheet_name="test1", index=False) + frame.to_excel(tmp_excel, sheet_name="test1") + frame.to_excel(tmp_excel, sheet_name="test1", columns=["A", "B"]) + frame.to_excel(tmp_excel, sheet_name="test1", header=False) + frame.to_excel(tmp_excel, sheet_name="test1", index=False) @pytest.mark.parametrize("np_type", [np.int8, np.int16, np.int32, np.int64]) - def test_int_types(self, np_type, path): + def test_int_types(self, np_type, tmp_excel): # Test np.int values read come back as int # (rather than float which is Excel's format). df = DataFrame( np.random.default_rng(2).integers(-10, 10, size=(10, 2)), dtype=np_type ) - df.to_excel(path, sheet_name="test1") + df.to_excel(tmp_excel, sheet_name="test1") - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0) int_frame = df.astype(np.int64) tm.assert_frame_equal(int_frame, recons) - recons2 = pd.read_excel(path, sheet_name="test1", index_col=0) + recons2 = pd.read_excel(tmp_excel, sheet_name="test1", index_col=0) tm.assert_frame_equal(int_frame, recons2) @pytest.mark.parametrize("np_type", [np.float16, np.float32, np.float64]) - def test_float_types(self, np_type, path): + def test_float_types(self, np_type, tmp_excel): # Test np.float values read come back as float. df = DataFrame(np.random.default_rng(2).random(10), dtype=np_type) - df.to_excel(path, sheet_name="test1") + df.to_excel(tmp_excel, sheet_name="test1") - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0).astype( np_type ) tm.assert_frame_equal(df, recons) - def test_bool_types(self, path): + def test_bool_types(self, tmp_excel): # Test np.bool_ values read come back as float. df = DataFrame([1, 0, True, False], dtype=np.bool_) - df.to_excel(path, sheet_name="test1") + df.to_excel(tmp_excel, sheet_name="test1") - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0).astype( np.bool_ ) tm.assert_frame_equal(df, recons) - def test_inf_roundtrip(self, path): + def test_inf_roundtrip(self, tmp_excel): df = DataFrame([(1, np.inf), (2, 3), (5, -np.inf)]) - df.to_excel(path, sheet_name="test1") + df.to_excel(tmp_excel, sheet_name="test1") - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(df, recons) - def test_sheets(self, frame, path): + def test_sheets(self, frame, tmp_excel): # freq doesn't round-trip - unit = get_exp_unit(path) + unit = get_exp_unit(tmp_excel) tsframe = DataFrame( np.random.default_rng(2).standard_normal((5, 4)), columns=Index(list("ABCD")), @@ -568,16 +569,16 @@ def test_sheets(self, frame, path): frame = frame.copy() frame.iloc[:5, frame.columns.get_loc("A")] = np.nan - frame.to_excel(path, sheet_name="test1") - frame.to_excel(path, sheet_name="test1", columns=["A", "B"]) - frame.to_excel(path, sheet_name="test1", header=False) - frame.to_excel(path, sheet_name="test1", index=False) + frame.to_excel(tmp_excel, sheet_name="test1") + frame.to_excel(tmp_excel, sheet_name="test1", columns=["A", "B"]) + frame.to_excel(tmp_excel, sheet_name="test1", header=False) + frame.to_excel(tmp_excel, sheet_name="test1", index=False) # Test writing to separate sheets - with ExcelWriter(path) as writer: + with ExcelWriter(tmp_excel) as writer: frame.to_excel(writer, sheet_name="test1") tsframe.to_excel(writer, sheet_name="test2") - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(frame, recons) recons = pd.read_excel(reader, sheet_name="test2", index_col=0) @@ -586,39 +587,39 @@ def test_sheets(self, frame, path): assert "test1" == reader.sheet_names[0] assert "test2" == reader.sheet_names[1] - def test_colaliases(self, frame, path): + def test_colaliases(self, frame, tmp_excel): frame = frame.copy() frame.iloc[:5, frame.columns.get_loc("A")] = np.nan - frame.to_excel(path, sheet_name="test1") - frame.to_excel(path, sheet_name="test1", columns=["A", "B"]) - frame.to_excel(path, sheet_name="test1", header=False) - frame.to_excel(path, sheet_name="test1", index=False) + frame.to_excel(tmp_excel, sheet_name="test1") + frame.to_excel(tmp_excel, sheet_name="test1", columns=["A", "B"]) + frame.to_excel(tmp_excel, sheet_name="test1", header=False) + frame.to_excel(tmp_excel, sheet_name="test1", index=False) # column aliases col_aliases = Index(["AA", "X", "Y", "Z"]) - frame.to_excel(path, sheet_name="test1", header=col_aliases) - with ExcelFile(path) as reader: + frame.to_excel(tmp_excel, sheet_name="test1", header=col_aliases) + with ExcelFile(tmp_excel) as reader: rs = pd.read_excel(reader, sheet_name="test1", index_col=0) xp = frame.copy() xp.columns = col_aliases tm.assert_frame_equal(xp, rs) - def test_roundtrip_indexlabels(self, merge_cells, frame, path): + def test_roundtrip_indexlabels(self, merge_cells, frame, tmp_excel): frame = frame.copy() frame.iloc[:5, frame.columns.get_loc("A")] = np.nan - frame.to_excel(path, sheet_name="test1") - frame.to_excel(path, sheet_name="test1", columns=["A", "B"]) - frame.to_excel(path, sheet_name="test1", header=False) - frame.to_excel(path, sheet_name="test1", index=False) + frame.to_excel(tmp_excel, sheet_name="test1") + frame.to_excel(tmp_excel, sheet_name="test1", columns=["A", "B"]) + frame.to_excel(tmp_excel, sheet_name="test1", header=False) + frame.to_excel(tmp_excel, sheet_name="test1", index=False) # test index_label df = DataFrame(np.random.default_rng(2).standard_normal((10, 2))) >= 0 df.to_excel( - path, sheet_name="test1", index_label=["test"], merge_cells=merge_cells + tmp_excel, sheet_name="test1", index_label=["test"], merge_cells=merge_cells ) - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0).astype( np.int64 ) @@ -627,12 +628,12 @@ def test_roundtrip_indexlabels(self, merge_cells, frame, path): df = DataFrame(np.random.default_rng(2).standard_normal((10, 2))) >= 0 df.to_excel( - path, + tmp_excel, sheet_name="test1", index_label=["test", "dummy", "dummy2"], merge_cells=merge_cells, ) - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0).astype( np.int64 ) @@ -641,9 +642,9 @@ def test_roundtrip_indexlabels(self, merge_cells, frame, path): df = DataFrame(np.random.default_rng(2).standard_normal((10, 2))) >= 0 df.to_excel( - path, sheet_name="test1", index_label="test", merge_cells=merge_cells + tmp_excel, sheet_name="test1", index_label="test", merge_cells=merge_cells ) - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0).astype( np.int64 ) @@ -651,7 +652,7 @@ def test_roundtrip_indexlabels(self, merge_cells, frame, path): tm.assert_frame_equal(df, recons.astype(bool)) frame.to_excel( - path, + tmp_excel, sheet_name="test1", columns=["A", "B", "C", "D"], index=False, @@ -661,25 +662,25 @@ def test_roundtrip_indexlabels(self, merge_cells, frame, path): df = frame.copy() df = df.set_index(["A", "B"]) - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=[0, 1]) tm.assert_frame_equal(df, recons) - def test_excel_roundtrip_indexname(self, merge_cells, path): + def test_excel_roundtrip_indexname(self, merge_cells, tmp_excel): df = DataFrame(np.random.default_rng(2).standard_normal((10, 4))) df.index.name = "foo" - df.to_excel(path, merge_cells=merge_cells) + df.to_excel(tmp_excel, merge_cells=merge_cells) - with ExcelFile(path) as xf: + with ExcelFile(tmp_excel) as xf: result = pd.read_excel(xf, sheet_name=xf.sheet_names[0], index_col=0) tm.assert_frame_equal(result, df) assert result.index.name == "foo" - def test_excel_roundtrip_datetime(self, merge_cells, path): + def test_excel_roundtrip_datetime(self, merge_cells, tmp_excel): # datetime.date, not sure what to test here exactly - unit = get_exp_unit(path) + unit = get_exp_unit(tmp_excel) # freq does not round-trip tsframe = DataFrame( @@ -693,20 +694,20 @@ def test_excel_roundtrip_datetime(self, merge_cells, path): tsf = tsframe.copy() tsf.index = [x.date() for x in tsframe.index] - tsf.to_excel(path, sheet_name="test1", merge_cells=merge_cells) + tsf.to_excel(tmp_excel, sheet_name="test1", merge_cells=merge_cells) - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0) expected = tsframe[:] expected.index = expected.index.as_unit(unit) tm.assert_frame_equal(expected, recons) - def test_excel_date_datetime_format(self, ext, path): + def test_excel_date_datetime_format(self, ext, tmp_excel, tmp_path): # see gh-4133 # # Excel output format strings - unit = get_exp_unit(path) + unit = get_exp_unit(tmp_excel) df = DataFrame( [ @@ -726,22 +727,23 @@ def test_excel_date_datetime_format(self, ext, path): ) df_expected = df_expected.astype(f"M8[{unit}]") - with tm.ensure_clean(ext) as filename2: - with ExcelWriter(path) as writer1: - df.to_excel(writer1, sheet_name="test1") + filename2 = tmp_path / f"tmp2{ext}" + filename2.touch() + with ExcelWriter(tmp_excel) as writer1: + df.to_excel(writer1, sheet_name="test1") - with ExcelWriter( - filename2, - date_format="DD.MM.YYYY", - datetime_format="DD.MM.YYYY HH-MM-SS", - ) as writer2: - df.to_excel(writer2, sheet_name="test1") + with ExcelWriter( + filename2, + date_format="DD.MM.YYYY", + datetime_format="DD.MM.YYYY HH-MM-SS", + ) as writer2: + df.to_excel(writer2, sheet_name="test1") - with ExcelFile(path) as reader1: - rs1 = pd.read_excel(reader1, sheet_name="test1", index_col=0) + with ExcelFile(tmp_excel) as reader1: + rs1 = pd.read_excel(reader1, sheet_name="test1", index_col=0) - with ExcelFile(filename2) as reader2: - rs2 = pd.read_excel(reader2, sheet_name="test1", index_col=0) + with ExcelFile(filename2) as reader2: + rs2 = pd.read_excel(reader2, sheet_name="test1", index_col=0) tm.assert_frame_equal(rs1, rs2) @@ -749,7 +751,7 @@ def test_excel_date_datetime_format(self, ext, path): # we need to use df_expected to check the result. tm.assert_frame_equal(rs2, df_expected) - def test_to_excel_interval_no_labels(self, path, using_infer_string): + def test_to_excel_interval_no_labels(self, tmp_excel, using_infer_string): # see gh-19242 # # Test writing Interval without labels. @@ -763,12 +765,12 @@ def test_to_excel_interval_no_labels(self, path, using_infer_string): str if not using_infer_string else "string[pyarrow_numpy]" ) - df.to_excel(path, sheet_name="test1") - with ExcelFile(path) as reader: + df.to_excel(tmp_excel, sheet_name="test1") + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(expected, recons) - def test_to_excel_interval_labels(self, path): + def test_to_excel_interval_labels(self, tmp_excel): # see gh-19242 # # Test writing Interval with labels. @@ -782,12 +784,12 @@ def test_to_excel_interval_labels(self, path): df["new"] = intervals expected["new"] = pd.Series(list(intervals)) - df.to_excel(path, sheet_name="test1") - with ExcelFile(path) as reader: + df.to_excel(tmp_excel, sheet_name="test1") + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(expected, recons) - def test_to_excel_timedelta(self, path): + def test_to_excel_timedelta(self, tmp_excel): # see gh-19242, gh-9155 # # Test writing timedelta to xls. @@ -803,12 +805,12 @@ def test_to_excel_timedelta(self, path): lambda x: timedelta(seconds=x).total_seconds() / 86400 ) - df.to_excel(path, sheet_name="test1") - with ExcelFile(path) as reader: + df.to_excel(tmp_excel, sheet_name="test1") + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(expected, recons) - def test_to_excel_periodindex(self, path): + def test_to_excel_periodindex(self, tmp_excel): # xp has a PeriodIndex df = DataFrame( np.random.default_rng(2).standard_normal((5, 4)), @@ -817,28 +819,28 @@ def test_to_excel_periodindex(self, path): ) xp = df.resample("ME").mean().to_period("M") - xp.to_excel(path, sheet_name="sht1") + xp.to_excel(tmp_excel, sheet_name="sht1") - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: rs = pd.read_excel(reader, sheet_name="sht1", index_col=0) tm.assert_frame_equal(xp, rs.to_period("M")) - def test_to_excel_multiindex(self, merge_cells, frame, path): + def test_to_excel_multiindex(self, merge_cells, frame, tmp_excel): arrays = np.arange(len(frame.index) * 2, dtype=np.int64).reshape(2, -1) new_index = MultiIndex.from_arrays(arrays, names=["first", "second"]) frame.index = new_index - frame.to_excel(path, sheet_name="test1", header=False) - frame.to_excel(path, sheet_name="test1", columns=["A", "B"]) + frame.to_excel(tmp_excel, sheet_name="test1", header=False) + frame.to_excel(tmp_excel, sheet_name="test1", columns=["A", "B"]) # round trip - frame.to_excel(path, sheet_name="test1", merge_cells=merge_cells) - with ExcelFile(path) as reader: + frame.to_excel(tmp_excel, sheet_name="test1", merge_cells=merge_cells) + with ExcelFile(tmp_excel) as reader: df = pd.read_excel(reader, sheet_name="test1", index_col=[0, 1]) tm.assert_frame_equal(frame, df) # GH13511 - def test_to_excel_multiindex_nan_label(self, merge_cells, path): + def test_to_excel_multiindex_nan_label(self, merge_cells, tmp_excel): df = DataFrame( { "A": [None, 2, 3], @@ -848,14 +850,14 @@ def test_to_excel_multiindex_nan_label(self, merge_cells, path): ) df = df.set_index(["A", "B"]) - df.to_excel(path, merge_cells=merge_cells) - df1 = pd.read_excel(path, index_col=[0, 1]) + df.to_excel(tmp_excel, merge_cells=merge_cells) + df1 = pd.read_excel(tmp_excel, index_col=[0, 1]) tm.assert_frame_equal(df, df1) # Test for Issue 11328. If column indices are integers, make # sure they are handled correctly for either setting of # merge_cells - def test_to_excel_multiindex_cols(self, merge_cells, frame, path): + def test_to_excel_multiindex_cols(self, merge_cells, frame, tmp_excel): arrays = np.arange(len(frame.index) * 2, dtype=np.int64).reshape(2, -1) new_index = MultiIndex.from_arrays(arrays, names=["first", "second"]) frame.index = new_index @@ -867,8 +869,8 @@ def test_to_excel_multiindex_cols(self, merge_cells, frame, path): header = 0 # round trip - frame.to_excel(path, sheet_name="test1", merge_cells=merge_cells) - with ExcelFile(path) as reader: + frame.to_excel(tmp_excel, sheet_name="test1", merge_cells=merge_cells) + with ExcelFile(tmp_excel) as reader: df = pd.read_excel( reader, sheet_name="test1", header=header, index_col=[0, 1] ) @@ -877,9 +879,9 @@ def test_to_excel_multiindex_cols(self, merge_cells, frame, path): frame.columns = [".".join(map(str, q)) for q in zip(*fm)] tm.assert_frame_equal(frame, df) - def test_to_excel_multiindex_dates(self, merge_cells, path): + def test_to_excel_multiindex_dates(self, merge_cells, tmp_excel): # try multiindex with dates - unit = get_exp_unit(path) + unit = get_exp_unit(tmp_excel) tsframe = DataFrame( np.random.default_rng(2).standard_normal((5, 4)), columns=Index(list("ABCD")), @@ -893,14 +895,14 @@ def test_to_excel_multiindex_dates(self, merge_cells, path): names=["time", "foo"], ) - tsframe.to_excel(path, sheet_name="test1", merge_cells=merge_cells) - with ExcelFile(path) as reader: + tsframe.to_excel(tmp_excel, sheet_name="test1", merge_cells=merge_cells) + with ExcelFile(tmp_excel) as reader: recons = pd.read_excel(reader, sheet_name="test1", index_col=[0, 1]) tm.assert_frame_equal(tsframe, recons) assert recons.index.names == ("time", "foo") - def test_to_excel_multiindex_no_write_index(self, path): + def test_to_excel_multiindex_no_write_index(self, tmp_excel): # Test writing and re-reading a MI without the index. GH 5616. # Initial non-MI frame. @@ -912,37 +914,37 @@ def test_to_excel_multiindex_no_write_index(self, path): frame2.index = multi_index # Write out to Excel without the index. - frame2.to_excel(path, sheet_name="test1", index=False) + frame2.to_excel(tmp_excel, sheet_name="test1", index=False) # Read it back in. - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: frame3 = pd.read_excel(reader, sheet_name="test1") # Test that it is the same as the initial frame. tm.assert_frame_equal(frame1, frame3) - def test_to_excel_empty_multiindex(self, path): + def test_to_excel_empty_multiindex(self, tmp_excel): # GH 19543. expected = DataFrame([], columns=[0, 1, 2]) df = DataFrame([], index=MultiIndex.from_tuples([], names=[0, 1]), columns=[2]) - df.to_excel(path, sheet_name="test1") + df.to_excel(tmp_excel, sheet_name="test1") - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: result = pd.read_excel(reader, sheet_name="test1") tm.assert_frame_equal( result, expected, check_index_type=False, check_dtype=False ) - def test_to_excel_float_format(self, path): + def test_to_excel_float_format(self, tmp_excel): df = DataFrame( [[0.123456, 0.234567, 0.567567], [12.32112, 123123.2, 321321.2]], index=["A", "B"], columns=["X", "Y", "Z"], ) - df.to_excel(path, sheet_name="test1", float_format="%.2f") + df.to_excel(tmp_excel, sheet_name="test1", float_format="%.2f") - with ExcelFile(path) as reader: + with ExcelFile(tmp_excel) as reader: result = pd.read_excel(reader, sheet_name="test1", index_col=0) expected = DataFrame( @@ -952,7 +954,7 @@ def test_to_excel_float_format(self, path): ) tm.assert_frame_equal(result, expected) - def test_to_excel_output_encoding(self, ext): + def test_to_excel_output_encoding(self, tmp_excel): # Avoid mixed inferred_type. df = DataFrame( [["\u0192", "\u0193", "\u0194"], ["\u0195", "\u0196", "\u0197"]], @@ -960,28 +962,22 @@ def test_to_excel_output_encoding(self, ext): columns=["X\u0193", "Y", "Z"], ) - with tm.ensure_clean("__tmp_to_excel_float_format__." + ext) as filename: - df.to_excel(filename, sheet_name="TestSheet") - result = pd.read_excel(filename, sheet_name="TestSheet", index_col=0) - tm.assert_frame_equal(result, df) - - def test_to_excel_unicode_filename(self, ext): - with tm.ensure_clean("\u0192u." + ext) as filename: - try: - with open(filename, "wb"): - pass - except UnicodeEncodeError: - pytest.skip("No unicode file names on this system") + df.to_excel(tmp_excel, sheet_name="TestSheet") + result = pd.read_excel(tmp_excel, sheet_name="TestSheet", index_col=0) + tm.assert_frame_equal(result, df) - df = DataFrame( - [[0.123456, 0.234567, 0.567567], [12.32112, 123123.2, 321321.2]], - index=["A", "B"], - columns=["X", "Y", "Z"], - ) - df.to_excel(filename, sheet_name="test1", float_format="%.2f") + def test_to_excel_unicode_filename(self, ext, tmp_path): + filename = tmp_path / f"\u0192u.{ext}" + filename.touch() + df = DataFrame( + [[0.123456, 0.234567, 0.567567], [12.32112, 123123.2, 321321.2]], + index=["A", "B"], + columns=["X", "Y", "Z"], + ) + df.to_excel(filename, sheet_name="test1", float_format="%.2f") - with ExcelFile(filename) as reader: - result = pd.read_excel(reader, sheet_name="test1", index_col=0) + with ExcelFile(filename) as reader: + result = pd.read_excel(reader, sheet_name="test1", index_col=0) expected = DataFrame( [[0.12, 0.23, 0.57], [12.32, 123123.20, 321321.20]], @@ -994,12 +990,14 @@ def test_to_excel_unicode_filename(self, ext): @pytest.mark.parametrize("r_idx_nlevels", [1, 2, 3]) @pytest.mark.parametrize("c_idx_nlevels", [1, 2, 3]) def test_excel_010_hemstring( - self, merge_cells, c_idx_nlevels, r_idx_nlevels, use_headers, path + self, merge_cells, c_idx_nlevels, r_idx_nlevels, use_headers, tmp_excel ): def roundtrip(data, header=True, parser_hdr=0, index=True): - data.to_excel(path, header=header, merge_cells=merge_cells, index=index) + data.to_excel( + tmp_excel, header=header, merge_cells=merge_cells, index=index + ) - with ExcelFile(path) as xf: + with ExcelFile(tmp_excel) as xf: return pd.read_excel( xf, sheet_name=xf.sheet_names[0], header=parser_hdr ) @@ -1062,56 +1060,56 @@ def roundtrip(data, header=True, parser_hdr=0, index=True): for c in range(len(res.columns)): assert res.iloc[r, c] is not np.nan - def test_duplicated_columns(self, path): + def test_duplicated_columns(self, tmp_excel): # see gh-5235 df = DataFrame([[1, 2, 3], [1, 2, 3], [1, 2, 3]], columns=["A", "B", "B"]) - df.to_excel(path, sheet_name="test1") + df.to_excel(tmp_excel, sheet_name="test1") expected = DataFrame( [[1, 2, 3], [1, 2, 3], [1, 2, 3]], columns=["A", "B", "B.1"] ) # By default, we mangle. - result = pd.read_excel(path, sheet_name="test1", index_col=0) + result = pd.read_excel(tmp_excel, sheet_name="test1", index_col=0) tm.assert_frame_equal(result, expected) # see gh-11007, gh-10970 df = DataFrame([[1, 2, 3, 4], [5, 6, 7, 8]], columns=["A", "B", "A", "B"]) - df.to_excel(path, sheet_name="test1") + df.to_excel(tmp_excel, sheet_name="test1") - result = pd.read_excel(path, sheet_name="test1", index_col=0) + result = pd.read_excel(tmp_excel, sheet_name="test1", index_col=0) expected = DataFrame( [[1, 2, 3, 4], [5, 6, 7, 8]], columns=["A", "B", "A.1", "B.1"] ) tm.assert_frame_equal(result, expected) # see gh-10982 - df.to_excel(path, sheet_name="test1", index=False, header=False) - result = pd.read_excel(path, sheet_name="test1", header=None) + df.to_excel(tmp_excel, sheet_name="test1", index=False, header=False) + result = pd.read_excel(tmp_excel, sheet_name="test1", header=None) expected = DataFrame([[1, 2, 3, 4], [5, 6, 7, 8]]) tm.assert_frame_equal(result, expected) - def test_swapped_columns(self, path): + def test_swapped_columns(self, tmp_excel): # Test for issue #5427. write_frame = DataFrame({"A": [1, 1, 1], "B": [2, 2, 2]}) - write_frame.to_excel(path, sheet_name="test1", columns=["B", "A"]) + write_frame.to_excel(tmp_excel, sheet_name="test1", columns=["B", "A"]) - read_frame = pd.read_excel(path, sheet_name="test1", header=0) + read_frame = pd.read_excel(tmp_excel, sheet_name="test1", header=0) tm.assert_series_equal(write_frame["A"], read_frame["A"]) tm.assert_series_equal(write_frame["B"], read_frame["B"]) - def test_invalid_columns(self, path): + def test_invalid_columns(self, tmp_excel): # see gh-10982 write_frame = DataFrame({"A": [1, 1, 1], "B": [2, 2, 2]}) with pytest.raises(KeyError, match="Not all names specified"): - write_frame.to_excel(path, sheet_name="test1", columns=["B", "C"]) + write_frame.to_excel(tmp_excel, sheet_name="test1", columns=["B", "C"]) with pytest.raises( KeyError, match="'passes columns are not ALL present dataframe'" ): - write_frame.to_excel(path, sheet_name="test1", columns=["C", "D"]) + write_frame.to_excel(tmp_excel, sheet_name="test1", columns=["C", "D"]) @pytest.mark.parametrize( "to_excel_index,read_excel_index_col", @@ -1120,81 +1118,88 @@ def test_invalid_columns(self, path): (False, None), # Dont include index in write to file ], ) - def test_write_subset_columns(self, path, to_excel_index, read_excel_index_col): + def test_write_subset_columns( + self, tmp_excel, to_excel_index, read_excel_index_col + ): # GH 31677 write_frame = DataFrame({"A": [1, 1, 1], "B": [2, 2, 2], "C": [3, 3, 3]}) write_frame.to_excel( - path, sheet_name="col_subset_bug", columns=["A", "B"], index=to_excel_index + tmp_excel, + sheet_name="col_subset_bug", + columns=["A", "B"], + index=to_excel_index, ) expected = write_frame[["A", "B"]] read_frame = pd.read_excel( - path, sheet_name="col_subset_bug", index_col=read_excel_index_col + tmp_excel, sheet_name="col_subset_bug", index_col=read_excel_index_col ) tm.assert_frame_equal(expected, read_frame) - def test_comment_arg(self, path): + def test_comment_arg(self, tmp_excel): # see gh-18735 # # Test the comment argument functionality to pd.read_excel. # Create file to read in. df = DataFrame({"A": ["one", "#one", "one"], "B": ["two", "two", "#two"]}) - df.to_excel(path, sheet_name="test_c") + df.to_excel(tmp_excel, sheet_name="test_c") # Read file without comment arg. - result1 = pd.read_excel(path, sheet_name="test_c", index_col=0) + result1 = pd.read_excel(tmp_excel, sheet_name="test_c", index_col=0) result1.iloc[1, 0] = None result1.iloc[1, 1] = None result1.iloc[2, 1] = None - result2 = pd.read_excel(path, sheet_name="test_c", comment="#", index_col=0) + result2 = pd.read_excel( + tmp_excel, sheet_name="test_c", comment="#", index_col=0 + ) tm.assert_frame_equal(result1, result2) - def test_comment_default(self, path): + def test_comment_default(self, tmp_excel): # Re issue #18735 # Test the comment argument default to pd.read_excel # Create file to read in df = DataFrame({"A": ["one", "#one", "one"], "B": ["two", "two", "#two"]}) - df.to_excel(path, sheet_name="test_c") + df.to_excel(tmp_excel, sheet_name="test_c") # Read file with default and explicit comment=None - result1 = pd.read_excel(path, sheet_name="test_c") - result2 = pd.read_excel(path, sheet_name="test_c", comment=None) + result1 = pd.read_excel(tmp_excel, sheet_name="test_c") + result2 = pd.read_excel(tmp_excel, sheet_name="test_c", comment=None) tm.assert_frame_equal(result1, result2) - def test_comment_used(self, path): + def test_comment_used(self, tmp_excel): # see gh-18735 # # Test the comment argument is working as expected when used. # Create file to read in. df = DataFrame({"A": ["one", "#one", "one"], "B": ["two", "two", "#two"]}) - df.to_excel(path, sheet_name="test_c") + df.to_excel(tmp_excel, sheet_name="test_c") # Test read_frame_comment against manually produced expected output. expected = DataFrame({"A": ["one", None, "one"], "B": ["two", None, None]}) - result = pd.read_excel(path, sheet_name="test_c", comment="#", index_col=0) + result = pd.read_excel(tmp_excel, sheet_name="test_c", comment="#", index_col=0) tm.assert_frame_equal(result, expected) - def test_comment_empty_line(self, path): + def test_comment_empty_line(self, tmp_excel): # Re issue #18735 # Test that pd.read_excel ignores commented lines at the end of file df = DataFrame({"a": ["1", "#2"], "b": ["2", "3"]}) - df.to_excel(path, index=False) + df.to_excel(tmp_excel, index=False) # Test that all-comment lines at EoF are ignored expected = DataFrame({"a": [1], "b": [2]}) - result = pd.read_excel(path, comment="#") + result = pd.read_excel(tmp_excel, comment="#") tm.assert_frame_equal(result, expected) - def test_datetimes(self, path): + def test_datetimes(self, tmp_excel): # Test writing and reading datetimes. For issue #9139. (xref #9185) - unit = get_exp_unit(path) + unit = get_exp_unit(tmp_excel) datetimes = [ datetime(2013, 1, 13, 1, 2, 3), datetime(2013, 1, 13, 2, 45, 56), @@ -1210,8 +1215,8 @@ def test_datetimes(self, path): ] write_frame = DataFrame({"A": datetimes}) - write_frame.to_excel(path, sheet_name="Sheet1") - read_frame = pd.read_excel(path, sheet_name="Sheet1", header=0) + write_frame.to_excel(tmp_excel, sheet_name="Sheet1") + read_frame = pd.read_excel(tmp_excel, sheet_name="Sheet1", header=0) expected = write_frame.astype(f"M8[{unit}]") tm.assert_series_equal(expected["A"], read_frame["A"]) @@ -1229,7 +1234,7 @@ def test_bytes_io(self, engine): reread_df = pd.read_excel(bio, index_col=0) tm.assert_frame_equal(df, reread_df) - def test_engine_kwargs(self, engine, path): + def test_engine_kwargs(self, engine, tmp_excel): # GH#52368 df = DataFrame([{"A": 1, "B": 2}, {"A": 3, "B": 4}]) @@ -1249,19 +1254,19 @@ def test_engine_kwargs(self, engine, path): ] = "Workbook.__init__() got an unexpected keyword argument 'foo'" # Handle change in error message for openpyxl (write and append mode) - if engine == "openpyxl" and not os.path.exists(path): + if engine == "openpyxl" and not os.path.exists(tmp_excel): msgs[ "openpyxl" ] = r"load_workbook() got an unexpected keyword argument 'foo'" with pytest.raises(TypeError, match=re.escape(msgs[engine])): df.to_excel( - path, + tmp_excel, engine=engine, engine_kwargs={"foo": "bar"}, ) - def test_write_lists_dict(self, path): + def test_write_lists_dict(self, tmp_excel): # see gh-8188. df = DataFrame( { @@ -1270,8 +1275,8 @@ def test_write_lists_dict(self, path): "str": ["apple", "banana", "cherry"], } ) - df.to_excel(path, sheet_name="Sheet1") - read = pd.read_excel(path, sheet_name="Sheet1", header=0, index_col=0) + df.to_excel(tmp_excel, sheet_name="Sheet1") + read = pd.read_excel(tmp_excel, sheet_name="Sheet1", header=0, index_col=0) expected = df.copy() expected.mixed = expected.mixed.apply(str) @@ -1279,32 +1284,32 @@ def test_write_lists_dict(self, path): tm.assert_frame_equal(read, expected) - def test_render_as_column_name(self, path): + def test_render_as_column_name(self, tmp_excel): # see gh-34331 df = DataFrame({"render": [1, 2], "data": [3, 4]}) - df.to_excel(path, sheet_name="Sheet1") - read = pd.read_excel(path, "Sheet1", index_col=0) + df.to_excel(tmp_excel, sheet_name="Sheet1") + read = pd.read_excel(tmp_excel, "Sheet1", index_col=0) expected = df tm.assert_frame_equal(read, expected) - def test_true_and_false_value_options(self, path): + def test_true_and_false_value_options(self, tmp_excel): # see gh-13347 df = DataFrame([["foo", "bar"]], columns=["col1", "col2"], dtype=object) with option_context("future.no_silent_downcasting", True): expected = df.replace({"foo": True, "bar": False}).astype("bool") - df.to_excel(path) + df.to_excel(tmp_excel) read_frame = pd.read_excel( - path, true_values=["foo"], false_values=["bar"], index_col=0 + tmp_excel, true_values=["foo"], false_values=["bar"], index_col=0 ) tm.assert_frame_equal(read_frame, expected) - def test_freeze_panes(self, path): + def test_freeze_panes(self, tmp_excel): # see gh-15160 expected = DataFrame([[1, 2], [3, 4]], columns=["col1", "col2"]) - expected.to_excel(path, sheet_name="Sheet1", freeze_panes=(1, 1)) + expected.to_excel(tmp_excel, sheet_name="Sheet1", freeze_panes=(1, 1)) - result = pd.read_excel(path, index_col=0) + result = pd.read_excel(tmp_excel, index_col=0) tm.assert_frame_equal(result, expected) def test_path_path_lib(self, engine, ext): @@ -1319,7 +1324,7 @@ def test_path_path_lib(self, engine, ext): result = tm.round_trip_pathlib(writer, reader, path=f"foo{ext}") tm.assert_frame_equal(result, df) - def test_merged_cell_custom_objects(self, path): + def test_merged_cell_custom_objects(self, tmp_excel): # see GH-27006 mi = MultiIndex.from_tuples( [ @@ -1328,8 +1333,8 @@ def test_merged_cell_custom_objects(self, path): ] ) expected = DataFrame(np.ones((2, 2), dtype="int64"), columns=mi) - expected.to_excel(path) - result = pd.read_excel(path, header=[0, 1], index_col=0) + expected.to_excel(tmp_excel) + result = pd.read_excel(tmp_excel, header=[0, 1], index_col=0) # need to convert PeriodIndexes to standard Indexes for assert equal expected.columns = expected.columns.set_levels( [[str(i) for i in mi.levels[0]], [str(i) for i in mi.levels[1]]], @@ -1338,56 +1343,51 @@ def test_merged_cell_custom_objects(self, path): tm.assert_frame_equal(result, expected) @pytest.mark.parametrize("dtype", [None, object]) - def test_raise_when_saving_timezones(self, dtype, tz_aware_fixture, path): + def test_raise_when_saving_timezones(self, dtype, tz_aware_fixture, tmp_excel): # GH 27008, GH 7056 tz = tz_aware_fixture data = pd.Timestamp("2019", tz=tz) df = DataFrame([data], dtype=dtype) with pytest.raises(ValueError, match="Excel does not support"): - df.to_excel(path) + df.to_excel(tmp_excel) data = data.to_pydatetime() df = DataFrame([data], dtype=dtype) with pytest.raises(ValueError, match="Excel does not support"): - df.to_excel(path) + df.to_excel(tmp_excel) - def test_excel_duplicate_columns_with_names(self, path): + def test_excel_duplicate_columns_with_names(self, tmp_excel): # GH#39695 df = DataFrame({"A": [0, 1], "B": [10, 11]}) - df.to_excel(path, columns=["A", "B", "A"], index=False) + df.to_excel(tmp_excel, columns=["A", "B", "A"], index=False) - result = pd.read_excel(path) + result = pd.read_excel(tmp_excel) expected = DataFrame([[0, 10, 0], [1, 11, 1]], columns=["A", "B", "A.1"]) tm.assert_frame_equal(result, expected) - def test_if_sheet_exists_raises(self, ext): + def test_if_sheet_exists_raises(self, tmp_excel): # GH 40230 msg = "if_sheet_exists is only valid in append mode (mode='a')" - with tm.ensure_clean(ext) as f: - with pytest.raises(ValueError, match=re.escape(msg)): - ExcelWriter(f, if_sheet_exists="replace") + with pytest.raises(ValueError, match=re.escape(msg)): + ExcelWriter(tmp_excel, if_sheet_exists="replace") - def test_excel_writer_empty_frame(self, engine, ext): + def test_excel_writer_empty_frame(self, engine, tmp_excel): # GH#45793 - with tm.ensure_clean(ext) as path: - with ExcelWriter(path, engine=engine) as writer: - DataFrame().to_excel(writer) - result = pd.read_excel(path) - expected = DataFrame() - tm.assert_frame_equal(result, expected) - - def test_to_excel_empty_frame(self, engine, ext): + with ExcelWriter(tmp_excel, engine=engine) as writer: + DataFrame().to_excel(writer) + result = pd.read_excel(tmp_excel) + expected = DataFrame() + tm.assert_frame_equal(result, expected) + + def test_to_excel_empty_frame(self, engine, tmp_excel): # GH#45793 - with tm.ensure_clean(ext) as path: - DataFrame().to_excel(path, engine=engine) - result = pd.read_excel(path) - expected = DataFrame() - tm.assert_frame_equal(result, expected) - - def test_to_excel_raising_warning_when_cell_character_exceed_limit( - self, path, engine - ): + DataFrame().to_excel(tmp_excel, engine=engine) + result = pd.read_excel(tmp_excel) + expected = DataFrame() + tm.assert_frame_equal(result, expected) + + def test_to_excel_raising_warning_when_cell_character_exceed_limit(self): # GH#56954 df = DataFrame({"A": ["a" * 32768]}) msg = "Cell contents too long, truncated to 32767 characters" @@ -1406,22 +1406,21 @@ class TestExcelWriterEngineTests: pytest.param(_OpenpyxlWriter, ".xlsx", marks=td.skip_if_no("openpyxl")), ], ) - def test_ExcelWriter_dispatch(self, klass, ext): - with tm.ensure_clean(ext) as path: - with ExcelWriter(path) as writer: - if ext == ".xlsx" and bool( - import_optional_dependency("xlsxwriter", errors="ignore") - ): - # xlsxwriter has preference over openpyxl if both installed - assert isinstance(writer, _XlsxWriter) - else: - assert isinstance(writer, klass) + def test_ExcelWriter_dispatch(self, klass, ext, tmp_excel): + with ExcelWriter(tmp_excel) as writer: + if ext == ".xlsx" and bool( + import_optional_dependency("xlsxwriter", errors="ignore") + ): + # xlsxwriter has preference over openpyxl if both installed + assert isinstance(writer, _XlsxWriter) + else: + assert isinstance(writer, klass) def test_ExcelWriter_dispatch_raises(self): with pytest.raises(ValueError, match="No engine"): ExcelWriter("nothing") - def test_register_writer(self): + def test_register_writer(self, tmp_path): class DummyClass(ExcelWriter): called_save = False called_write_cells = False @@ -1453,38 +1452,41 @@ def assert_called_and_reset(cls): register_writer(DummyClass) with option_context("io.excel.xlsx.writer", "dummy"): - path = "something.xlsx" - with tm.ensure_clean(path) as filepath: - with ExcelWriter(filepath) as writer: - assert isinstance(writer, DummyClass) - df = DataFrame( - ["a"], - columns=Index(["b"], name="foo"), - index=Index(["c"], name="bar"), - ) - df.to_excel(filepath) + filepath = tmp_path / "something.xlsx" + filepath.touch() + with ExcelWriter(filepath) as writer: + assert isinstance(writer, DummyClass) + df = DataFrame( + ["a"], + columns=Index(["b"], name="foo"), + index=Index(["c"], name="bar"), + ) + df.to_excel(filepath) DummyClass.assert_called_and_reset() - with tm.ensure_clean("something.xls") as filepath: - df.to_excel(filepath, engine="dummy") + filepath2 = tmp_path / "something2.xlsx" + filepath2.touch() + df.to_excel(filepath2, engine="dummy") DummyClass.assert_called_and_reset() @td.skip_if_no("xlrd") @td.skip_if_no("openpyxl") class TestFSPath: - def test_excelfile_fspath(self): - with tm.ensure_clean("foo.xlsx") as path: - df = DataFrame({"A": [1, 2]}) - df.to_excel(path) - with ExcelFile(path) as xl: - result = os.fspath(xl) - assert result == path - - def test_excelwriter_fspath(self): - with tm.ensure_clean("foo.xlsx") as path: - with ExcelWriter(path) as writer: - assert os.fspath(writer) == str(path) + def test_excelfile_fspath(self, tmp_path): + path = tmp_path / "foo.xlsx" + path.touch() + df = DataFrame({"A": [1, 2]}) + df.to_excel(path) + with ExcelFile(path) as xl: + result = os.fspath(xl) + assert result == str(path) + + def test_excelwriter_fspath(self, tmp_path): + path = tmp_path / "foo.xlsx" + path.touch() + with ExcelWriter(path) as writer: + assert os.fspath(writer) == str(path) @pytest.mark.parametrize("klass", _writers.values()) diff --git a/pandas/tests/io/excel/test_xlsxwriter.py b/pandas/tests/io/excel/test_xlsxwriter.py index 94f6bdfaf069c..b4c0a3bd692d1 100644 --- a/pandas/tests/io/excel/test_xlsxwriter.py +++ b/pandas/tests/io/excel/test_xlsxwriter.py @@ -3,7 +3,6 @@ import pytest from pandas import DataFrame -import pandas._testing as tm from pandas.io.excel import ExcelWriter @@ -15,67 +14,73 @@ def ext(): return ".xlsx" -def test_column_format(ext): +@pytest.fixture +def tmp_excel(ext, tmp_path): + tmp = tmp_path / f"tmp{ext}" + tmp.touch() + yield str(tmp) + tmp.unlink() + + +def test_column_format(tmp_excel): # Test that column formats are applied to cells. Test for issue #9167. # Applicable to xlsxwriter only. openpyxl = pytest.importorskip("openpyxl") - with tm.ensure_clean(ext) as path: - frame = DataFrame({"A": [123456, 123456], "B": [123456, 123456]}) + frame = DataFrame({"A": [123456, 123456], "B": [123456, 123456]}) - with ExcelWriter(path) as writer: - frame.to_excel(writer) + with ExcelWriter(tmp_excel) as writer: + frame.to_excel(writer) - # Add a number format to col B and ensure it is applied to cells. - num_format = "#,##0" - write_workbook = writer.book - write_worksheet = write_workbook.worksheets()[0] - col_format = write_workbook.add_format({"num_format": num_format}) - write_worksheet.set_column("B:B", None, col_format) + # Add a number format to col B and ensure it is applied to cells. + num_format = "#,##0" + write_workbook = writer.book + write_worksheet = write_workbook.worksheets()[0] + col_format = write_workbook.add_format({"num_format": num_format}) + write_worksheet.set_column("B:B", None, col_format) - with contextlib.closing(openpyxl.load_workbook(path)) as read_workbook: - try: - read_worksheet = read_workbook["Sheet1"] - except TypeError: - # compat - read_worksheet = read_workbook.get_sheet_by_name(name="Sheet1") - - # Get the number format from the cell. + with contextlib.closing(openpyxl.load_workbook(tmp_excel)) as read_workbook: try: - cell = read_worksheet["B2"] + read_worksheet = read_workbook["Sheet1"] except TypeError: # compat - cell = read_worksheet.cell("B2") + read_worksheet = read_workbook.get_sheet_by_name(name="Sheet1") - try: - read_num_format = cell.number_format - except AttributeError: - read_num_format = cell.style.number_format._format_code + # Get the number format from the cell. + try: + cell = read_worksheet["B2"] + except TypeError: + # compat + cell = read_worksheet.cell("B2") + + try: + read_num_format = cell.number_format + except AttributeError: + read_num_format = cell.style.number_format._format_code - assert read_num_format == num_format + assert read_num_format == num_format -def test_write_append_mode_raises(ext): +def test_write_append_mode_raises(tmp_excel): msg = "Append mode is not supported with xlsxwriter!" - with tm.ensure_clean(ext) as f: - with pytest.raises(ValueError, match=msg): - ExcelWriter(f, engine="xlsxwriter", mode="a") + with pytest.raises(ValueError, match=msg): + ExcelWriter(tmp_excel, engine="xlsxwriter", mode="a") @pytest.mark.parametrize("nan_inf_to_errors", [True, False]) -def test_engine_kwargs(ext, nan_inf_to_errors): +def test_engine_kwargs(tmp_excel, nan_inf_to_errors): # GH 42286 engine_kwargs = {"options": {"nan_inf_to_errors": nan_inf_to_errors}} - with tm.ensure_clean(ext) as f: - with ExcelWriter(f, engine="xlsxwriter", engine_kwargs=engine_kwargs) as writer: - assert writer.book.nan_inf_to_errors == nan_inf_to_errors + with ExcelWriter( + tmp_excel, engine="xlsxwriter", engine_kwargs=engine_kwargs + ) as writer: + assert writer.book.nan_inf_to_errors == nan_inf_to_errors -def test_book_and_sheets_consistent(ext): +def test_book_and_sheets_consistent(tmp_excel): # GH#45687 - Ensure sheets is updated if user modifies book - with tm.ensure_clean(ext) as f: - with ExcelWriter(f, engine="xlsxwriter") as writer: - assert writer.sheets == {} - sheet = writer.book.add_worksheet("test_name") - assert writer.sheets == {"test_name": sheet} + with ExcelWriter(tmp_excel, engine="xlsxwriter") as writer: + assert writer.sheets == {} + sheet = writer.book.add_worksheet("test_name") + assert writer.sheets == {"test_name": sheet} From b5e5991f554ce5cd3ce8c6ad853e31924fec222e Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Mon, 19 Feb 2024 21:48:38 -0800 Subject: [PATCH 3/4] uuid4? --- pandas/tests/io/excel/test_odswriter.py | 3 ++- pandas/tests/io/excel/test_openpyxl.py | 3 ++- pandas/tests/io/excel/test_readers.py | 3 ++- pandas/tests/io/excel/test_style.py | 3 ++- pandas/tests/io/excel/test_writers.py | 3 ++- pandas/tests/io/excel/test_xlsxwriter.py | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pandas/tests/io/excel/test_odswriter.py b/pandas/tests/io/excel/test_odswriter.py index b319de3235ce3..60fe51a6ed9de 100644 --- a/pandas/tests/io/excel/test_odswriter.py +++ b/pandas/tests/io/excel/test_odswriter.py @@ -3,6 +3,7 @@ datetime, ) import re +import uuid import pytest @@ -20,7 +21,7 @@ def ext(): @pytest.fixture def tmp_excel(ext, tmp_path): - tmp = tmp_path / f"tmp{ext}" + tmp = tmp_path / f"{uuid.uuid4()}{ext}" tmp.touch() yield str(tmp) tmp.unlink() diff --git a/pandas/tests/io/excel/test_openpyxl.py b/pandas/tests/io/excel/test_openpyxl.py index 16e6002f75e75..3c632fb60f74b 100644 --- a/pandas/tests/io/excel/test_openpyxl.py +++ b/pandas/tests/io/excel/test_openpyxl.py @@ -1,6 +1,7 @@ import contextlib from pathlib import Path import re +import uuid import numpy as np import pytest @@ -25,7 +26,7 @@ def ext(): @pytest.fixture def tmp_excel(ext, tmp_path): - tmp = tmp_path / f"tmp{ext}" + tmp = tmp_path / f"{uuid.uuid4()}{ext}" tmp.touch() yield str(tmp) tmp.unlink() diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index 482b2b7b719e3..ca956b2244266 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -11,6 +11,7 @@ import platform import re from urllib.error import URLError +import uuid from zipfile import BadZipFile import numpy as np @@ -124,7 +125,7 @@ def read_ext(engine_and_read_ext): @pytest.fixture def tmp_excel(read_ext, tmp_path): - tmp = tmp_path / f"tmp{read_ext}" + tmp = tmp_path / f"{uuid.uuid4()}{read_ext}" tmp.touch() yield str(tmp) tmp.unlink() diff --git a/pandas/tests/io/excel/test_style.py b/pandas/tests/io/excel/test_style.py index b50e6291d92e9..5e2535f7ddbbf 100644 --- a/pandas/tests/io/excel/test_style.py +++ b/pandas/tests/io/excel/test_style.py @@ -1,5 +1,6 @@ import contextlib import time +import uuid import numpy as np import pytest @@ -23,7 +24,7 @@ @pytest.fixture def tmp_excel(tmp_path): - tmp = tmp_path / "tmp.xlsx" + tmp = tmp_path / f"{uuid.uuid4()}.xlsx" tmp.touch() yield str(tmp) tmp.unlink() diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 48142a91079b5..48c052350bcc3 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -7,6 +7,7 @@ from io import BytesIO import os import re +import uuid import numpy as np import pytest @@ -57,7 +58,7 @@ def tmp_excel(ext, tmp_path): """ Fixture to open file for use in each test case. """ - tmp = tmp_path / f"tmp{ext}" + tmp = tmp_path / f"{uuid.uuid4()}{ext}" tmp.touch() yield str(tmp) tmp.unlink() diff --git a/pandas/tests/io/excel/test_xlsxwriter.py b/pandas/tests/io/excel/test_xlsxwriter.py index b4c0a3bd692d1..090dd41bb9213 100644 --- a/pandas/tests/io/excel/test_xlsxwriter.py +++ b/pandas/tests/io/excel/test_xlsxwriter.py @@ -1,4 +1,5 @@ import contextlib +import uuid import pytest @@ -16,7 +17,7 @@ def ext(): @pytest.fixture def tmp_excel(ext, tmp_path): - tmp = tmp_path / f"tmp{ext}" + tmp = tmp_path / f"{uuid.uuid4()}{ext}" tmp.touch() yield str(tmp) tmp.unlink() From 8e8594d8df95028a5710626673fddf3ec31bcbf3 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:07:35 -0800 Subject: [PATCH 4/4] Don't remove, pytest cleans itself up eventually --- pandas/tests/io/excel/test_odswriter.py | 3 +-- pandas/tests/io/excel/test_openpyxl.py | 3 +-- pandas/tests/io/excel/test_readers.py | 3 +-- pandas/tests/io/excel/test_style.py | 3 +-- pandas/tests/io/excel/test_writers.py | 3 +-- pandas/tests/io/excel/test_xlsxwriter.py | 3 +-- 6 files changed, 6 insertions(+), 12 deletions(-) diff --git a/pandas/tests/io/excel/test_odswriter.py b/pandas/tests/io/excel/test_odswriter.py index 60fe51a6ed9de..7843bb59f97cf 100644 --- a/pandas/tests/io/excel/test_odswriter.py +++ b/pandas/tests/io/excel/test_odswriter.py @@ -23,8 +23,7 @@ def ext(): def tmp_excel(ext, tmp_path): tmp = tmp_path / f"{uuid.uuid4()}{ext}" tmp.touch() - yield str(tmp) - tmp.unlink() + return str(tmp) def test_write_append_mode_raises(tmp_excel): diff --git a/pandas/tests/io/excel/test_openpyxl.py b/pandas/tests/io/excel/test_openpyxl.py index 3c632fb60f74b..5b4bbb9e686d3 100644 --- a/pandas/tests/io/excel/test_openpyxl.py +++ b/pandas/tests/io/excel/test_openpyxl.py @@ -28,8 +28,7 @@ def ext(): def tmp_excel(ext, tmp_path): tmp = tmp_path / f"{uuid.uuid4()}{ext}" tmp.touch() - yield str(tmp) - tmp.unlink() + return str(tmp) def test_to_excel_styleconverter(): diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index ca956b2244266..f0a72ba6163fa 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -127,8 +127,7 @@ def read_ext(engine_and_read_ext): def tmp_excel(read_ext, tmp_path): tmp = tmp_path / f"{uuid.uuid4()}{read_ext}" tmp.touch() - yield str(tmp) - tmp.unlink() + return str(tmp) @pytest.fixture diff --git a/pandas/tests/io/excel/test_style.py b/pandas/tests/io/excel/test_style.py index 5e2535f7ddbbf..f70e65e34c584 100644 --- a/pandas/tests/io/excel/test_style.py +++ b/pandas/tests/io/excel/test_style.py @@ -26,8 +26,7 @@ def tmp_excel(tmp_path): tmp = tmp_path / f"{uuid.uuid4()}.xlsx" tmp.touch() - yield str(tmp) - tmp.unlink() + return str(tmp) def assert_equal_cell_styles(cell1, cell2): diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 48c052350bcc3..ca5c98f49f09c 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -60,8 +60,7 @@ def tmp_excel(ext, tmp_path): """ tmp = tmp_path / f"{uuid.uuid4()}{ext}" tmp.touch() - yield str(tmp) - tmp.unlink() + return str(tmp) @pytest.fixture diff --git a/pandas/tests/io/excel/test_xlsxwriter.py b/pandas/tests/io/excel/test_xlsxwriter.py index 090dd41bb9213..b2e6c845e5019 100644 --- a/pandas/tests/io/excel/test_xlsxwriter.py +++ b/pandas/tests/io/excel/test_xlsxwriter.py @@ -19,8 +19,7 @@ def ext(): def tmp_excel(ext, tmp_path): tmp = tmp_path / f"{uuid.uuid4()}{ext}" tmp.touch() - yield str(tmp) - tmp.unlink() + return str(tmp) def test_column_format(tmp_excel):