From 5f4e4aafed98578732cf3ffd05e0fef7bf6d4373 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Tue, 28 Dec 2021 17:09:03 -0800 Subject: [PATCH 01/15] CI: Ensure all minimum optional dependencies are tested --- .github/workflows/posix.yml | 4 +- ci/deps/actions-38-db-min.yaml | 45 ------------------- ...yaml => actions-38-downstream_compat.yaml} | 42 ++++++++++------- ci/deps/actions-38-locale.yaml | 2 +- ci/deps/actions-38-locale_slow.yaml | 20 ++++----- ci/deps/actions-38-minimum_versions.yaml | 33 +++++++++++--- ci/deps/actions-38.yaml | 2 +- 7 files changed, 67 insertions(+), 81 deletions(-) delete mode 100644 ci/deps/actions-38-db-min.yaml rename ci/deps/{actions-38-db.yaml => actions-38-downstream_compat.yaml} (76%) diff --git a/.github/workflows/posix.yml b/.github/workflows/posix.yml index 2a40be680c681..bc3ee2e500d22 100644 --- a/.github/workflows/posix.yml +++ b/.github/workflows/posix.yml @@ -25,8 +25,8 @@ jobs: strategy: matrix: settings: [ - [actions-38-db-min.yaml, "((not slow and not network and not clipboard) or (single and db))", "", "", "", "", ""], - [actions-38-db.yaml, "((not slow and not network and not clipboard) or (single and db))", "", "", "", "", ""], + [actions-38-downstream_compat.yaml, "not slow and not network and not clipboard", "", "", "", "", ""], + [actions-38-minimum_versions.yaml, "slow", "", "", "", "", ""], [actions-38-minimum_versions.yaml, "not slow and not network and not clipboard", "", "", "", "", ""], [actions-38-locale_slow.yaml, "slow", "language-pack-it xsel", "it_IT.utf8", "it_IT.utf8", "", ""], [actions-38.yaml, "not slow and not clipboard", "", "", "", "", ""], diff --git a/ci/deps/actions-38-db-min.yaml b/ci/deps/actions-38-db-min.yaml deleted file mode 100644 index f2b5a49ebfa97..0000000000000 --- a/ci/deps/actions-38-db-min.yaml +++ /dev/null @@ -1,45 +0,0 @@ -name: pandas-dev -channels: - - conda-forge -dependencies: - - python=3.8 - - # tools - - cython>=0.29.24 - - pytest>=6.0 - - pytest-cov - - pytest-xdist>=1.31 - - hypothesis>=5.5.3 - - # required - - numpy<1.20 # GH#39541 compat for pyarrow<3 - - python-dateutil - - pytz - - # optional - - beautifulsoup4 - - blosc=1.20.1 - - python-blosc - - fastparquet=0.4.0 - - html5lib - - ipython - - jinja2 - - lxml=4.5.0 - - matplotlib - - nomkl - - numexpr - - openpyxl - - pandas-gbq - - protobuf>=3.12.4 - - pyarrow=1.0.1 - - pytables>=3.6.1 - - scipy - - xarray=0.15.1 - - xlrd - - xlsxwriter - - xlwt - - # sql - - psycopg2=2.8.4 - - pymysql=0.10.1 - - sqlalchemy=1.4.0 diff --git a/ci/deps/actions-38-db.yaml b/ci/deps/actions-38-downstream_compat.yaml similarity index 76% rename from ci/deps/actions-38-db.yaml rename to ci/deps/actions-38-downstream_compat.yaml index ced15bbc8d7cb..d23a0e93b3a64 100644 --- a/ci/deps/actions-38-db.yaml +++ b/ci/deps/actions-38-downstream_compat.yaml @@ -1,3 +1,4 @@ +# Non-dependencies that pandas utilizes or has compatibility with pandas objects name: pandas-dev channels: - conda-forge @@ -5,28 +6,30 @@ dependencies: - python=3.8 - pip - # tools + # test dependencies - cython>=0.29.24 - pytest>=6.0 - pytest-xdist>=1.31 - hypothesis>=5.5.3 - pytest-cov>=2.10.1 # this is only needed in the coverage build, ref: GH 35737 + - nomkl - # pandas dependencies - - aiobotocore<2.0.0 # GH#44311 pinned to fix docbuild + # required dependencies + - numpy + - python-dateutil + - pytz + + # optional dependencies - beautifulsoup4 - - boto3 - - botocore>=1.11 - - dask + - blosc - fastparquet>=0.4.0 - fsspec>=0.7.4 - - gcsfs>=0.6.0 - - geopandas + - gcsfs - html5lib + - jinja2 + - lxml - matplotlib - - nomkl - numexpr - - numpy=1.18 - odfpy - openpyxl - pandas-gbq @@ -34,21 +37,28 @@ dependencies: - pyarrow>=1.0.1 - pymysql - pytables - - python-snappy - - python-dateutil - - pytz + - pyxlsb - s3fs>=0.4.0 - - scikit-learn - scipy - sqlalchemy - - statsmodels - xarray - xlrd - xlsxwriter - xlwt + + # downstream packages + - aiobotocore<2.0.0 # GH#44311 pinned to fix docbuild + - boto3 + - botocore>=1.11 + - dask + - ipython + - geopandas + - python-snappy + - scikit-learn + - statsmodels - brotlipy - coverage - pandas-datareader - - pyxlsb + - pyyaml - pip: - torch diff --git a/ci/deps/actions-38-locale.yaml b/ci/deps/actions-38-locale.yaml index b9157a1e74b1c..ef2288e2a24a6 100644 --- a/ci/deps/actions-38-locale.yaml +++ b/ci/deps/actions-38-locale.yaml @@ -19,7 +19,7 @@ dependencies: - jinja2 - jedi - lxml - - matplotlib<3.3.0 + - matplotlib - nomkl - numexpr - numpy<1.20 # GH#39541 compat with pyarrow<3 diff --git a/ci/deps/actions-38-locale_slow.yaml b/ci/deps/actions-38-locale_slow.yaml index e90acafa8bb2b..b16153398163b 100644 --- a/ci/deps/actions-38-locale_slow.yaml +++ b/ci/deps/actions-38-locale_slow.yaml @@ -13,18 +13,18 @@ dependencies: - hypothesis>=5.5.3 # pandas dependencies - - beautifulsoup4=4.8.2 - - bottleneck=1.3.1 + - beautifulsoup4 + - bottleneck - lxml - - matplotlib=3.3.2 - - numpy=1.18 - - openpyxl=3.0.2 + - matplotlib + - numpy + - openpyxl - python-dateutil - python-blosc - pytz=2020.1 - scipy - - sqlalchemy=1.4.0 - - xlrd=2.0.1 - - xlsxwriter=1.2.2 - - xlwt=1.3.0 - - html5lib=1.1 + - sqlalchemy + - xlrd + - xlsxwriter + - xlwt + - html5lib diff --git a/ci/deps/actions-38-minimum_versions.yaml b/ci/deps/actions-38-minimum_versions.yaml index cc1fd022ad24c..3446e1c631070 100644 --- a/ci/deps/actions-38-minimum_versions.yaml +++ b/ci/deps/actions-38-minimum_versions.yaml @@ -1,10 +1,12 @@ +# Minimum version of required + optional dependencies +# Aligned with getting_started/install.rst and compat/_optional.py name: pandas-dev channels: - conda-forge dependencies: - python=3.8.0 - # tools + # test dependencies - cython=0.29.24 - pytest>=6.0 - pytest-cov @@ -12,20 +14,39 @@ dependencies: - hypothesis>=5.5.3 - psutil - # pandas dependencies + # required dependencies + - python-dateutil=2.8.1 + - numpy=1.18.5 + - pytz=2020.1 + + # optional dependencies - beautifulsoup4=4.8.2 + - blosc=1.20.1 - bottleneck=1.3.1 + - fastparquet=0.4.0 + - fsspec=0.7.4 + - html5lib=1.1 + - gcsfs=0.6.0 - jinja2=2.11 + - lmxl=4.5.0 + - matplotlib=3.3.2 - numba=0.50.1 - numexpr=2.7.1 - - numpy=1.18.5 - openpyxl=3.0.2 + - odfpy=1.4.1 + - pandas-gbq=0.14.0 + - psycopg2=2.8.4 + - pymysql=0.10.1 - pytables=3.6.1 - - python-dateutil=2.8.1 - - pytz=2020.1 - pyarrow=1.0.1 + - pyreadstat + - pyxlsb=1.0.6 + - s3fs=0.4.0 - scipy=1.4.1 + - sqlalchemy=1.4.0 + - tabulate=0.8.7 + - xarray=0.15.1 - xlrd=2.0.1 - xlsxwriter=1.2.2 - xlwt=1.3.0 - - html5lib=1.1 + - zstandard=0.15.2 diff --git a/ci/deps/actions-38.yaml b/ci/deps/actions-38.yaml index 899913d6e8c70..2ad31ce82b855 100644 --- a/ci/deps/actions-38.yaml +++ b/ci/deps/actions-38.yaml @@ -17,4 +17,4 @@ dependencies: - python-dateutil - nomkl - pytz - - tabulate==0.8.7 + - tabulate From de605c5404b4179b1314e947a1a0e9c80d095871 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Tue, 28 Dec 2021 19:37:05 -0800 Subject: [PATCH 02/15] Typo in lxml --- ci/deps/actions-38-minimum_versions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deps/actions-38-minimum_versions.yaml b/ci/deps/actions-38-minimum_versions.yaml index 3446e1c631070..6ea9efc8833e2 100644 --- a/ci/deps/actions-38-minimum_versions.yaml +++ b/ci/deps/actions-38-minimum_versions.yaml @@ -28,7 +28,7 @@ dependencies: - html5lib=1.1 - gcsfs=0.6.0 - jinja2=2.11 - - lmxl=4.5.0 + - lxml=4.5.0 - matplotlib=3.3.2 - numba=0.50.1 - numexpr=2.7.1 From c6e6e38bcb45ab472a99473d7a9df85e1f6ab870 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Tue, 28 Dec 2021 22:45:25 -0800 Subject: [PATCH 03/15] xfail tests that fail on the min build --- pandas/tests/io/excel/test_openpyxl.py | 20 +++++++++++++++++++- pandas/tests/io/test_fsspec.py | 15 ++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/pandas/tests/io/excel/test_openpyxl.py b/pandas/tests/io/excel/test_openpyxl.py index e0d4a0c12ecdf..82b118f99a77a 100644 --- a/pandas/tests/io/excel/test_openpyxl.py +++ b/pandas/tests/io/excel/test_openpyxl.py @@ -4,6 +4,11 @@ import numpy as np import pytest +from pandas.compat._optional import ( + VERSIONS, + import_optional_dependency, +) + import pandas as pd from pandas import DataFrame import pandas._testing as tm @@ -51,9 +56,22 @@ def test_to_excel_styleconverter(ext): assert kw["protection"] == protection -def test_write_cells_merge_styled(ext): +def test_write_cells_merge_styled(request, ext): + import openpyxl + from pandas.io.formats.excel import ExcelCell + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and ext == ".xlsx" + and lxml is not None + and lxml.__version__ == VERSIONS["lxml"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) sheet_name = "merge_styled" sty_b1 = {"font": {"color": "00FF0000"}} diff --git a/pandas/tests/io/test_fsspec.py b/pandas/tests/io/test_fsspec.py index bbfed852d8b38..3a575d54d9d11 100644 --- a/pandas/tests/io/test_fsspec.py +++ b/pandas/tests/io/test_fsspec.py @@ -3,6 +3,8 @@ import numpy as np import pytest +from pandas.compat._optional import VERSIONS + from pandas import ( DataFrame, date_range, @@ -289,7 +291,18 @@ def test_stata_options(fsspectest): @td.skip_if_no("tabulate") -def test_markdown_options(fsspectest): +def test_markdown_options(request, fsspectest): + import fsspec + import tabulate + + request.node.add_marker( + pytest.mark.xfail( + fsspec.__version__ == VERSIONS["fsspec"] + and tabulate.__version__ == VERSIONS["tabulate"], + reason="Fails on the min version build", + raises=KeyError, + ) + ) df = DataFrame({"a": [0]}) df.to_markdown("testmem://afile", storage_options={"test": "md_write"}) assert fsspectest.test[0] == "md_write" From 598ba83ebc4b7d2ac33e04ed73dc5d1ca5fed562 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Wed, 29 Dec 2021 11:40:42 -0800 Subject: [PATCH 04/15] xfail more openpyxl tests with lxml --- pandas/tests/io/excel/test_openpyxl.py | 141 +++++++++++++++++++++++-- pandas/tests/io/test_fsspec.py | 7 +- 2 files changed, 136 insertions(+), 12 deletions(-) diff --git a/pandas/tests/io/excel/test_openpyxl.py b/pandas/tests/io/excel/test_openpyxl.py index 82b118f99a77a..2bf55ea48bbdb 100644 --- a/pandas/tests/io/excel/test_openpyxl.py +++ b/pandas/tests/io/excel/test_openpyxl.py @@ -67,7 +67,7 @@ def test_write_cells_merge_styled(request, ext): openpyxl.__version__ == VERSIONS["openpyxl"] and ext == ".xlsx" and lxml is not None - and lxml.__version__ == VERSIONS["lxml"], + and lxml.__version__ == VERSIONS["lxml.etree"], reason="Fails on the min version build", raises=TypeError, ) @@ -104,8 +104,21 @@ def test_write_cells_merge_styled(request, ext): @pytest.mark.parametrize("iso_dates", [True, False]) -def test_kwargs(ext, iso_dates): +def test_kwargs(request, ext, iso_dates): # GH 42286 GH 43445 + import openpyxl + + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and ext == ".xlsx" + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) kwargs = {"iso_dates": iso_dates} with tm.ensure_clean(ext) as f: msg = re.escape("Use of **kwargs is deprecated") @@ -117,8 +130,21 @@ def test_kwargs(ext, iso_dates): @pytest.mark.parametrize("iso_dates", [True, False]) -def test_engine_kwargs_write(ext, iso_dates): +def test_engine_kwargs_write(request, ext, iso_dates): # GH 42286 GH 43445 + import openpyxl + + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and ext == ".xlsx" + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) engine_kwargs = {"iso_dates": iso_dates} with tm.ensure_clean(ext) as f: with ExcelWriter(f, engine="openpyxl", engine_kwargs=engine_kwargs) as writer: @@ -146,10 +172,23 @@ def test_engine_kwargs_append_invalid(ext): @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(request, ext, data_only, expected): # GH 43445 # tests whether the data_only engine_kwarg actually works well for # openpyxl's load_workbook + import openpyxl + + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and ext == ".xlsx" + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) with tm.ensure_clean(ext) as f: DataFrame(["=1+1"]).to_excel(f) with ExcelWriter( @@ -163,7 +202,20 @@ def test_engine_kwargs_append_data_only(ext, data_only, expected): @pytest.mark.parametrize( "mode,expected", [("w", ["baz"]), ("a", ["foo", "bar", "baz"])] ) -def test_write_append_mode(ext, mode, expected): +def test_write_append_mode(request, ext, mode, expected): + import openpyxl + + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and ext == ".xlsx" + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame([1], columns=["baz"]) with tm.ensure_clean(ext) as f: @@ -193,8 +245,23 @@ 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( + request, ext, if_sheet_exists, num_sheets, expected +): # GH 40230 + import openpyxl + + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and ext == ".xlsx" + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) df1 = DataFrame({"fruit": ["apple", "banana"]}) df2 = DataFrame({"fruit": ["pear"]}) @@ -225,7 +292,22 @@ 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( + request, ext, startrow, startcol, greeting, goodbye +): + import openpyxl + + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and ext == ".xlsx" + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) df1 = DataFrame({"greeting": ["hello", "world"], "goodbye": ["goodbye", "people"]}) df2 = DataFrame(["poop"]) @@ -267,8 +349,21 @@ 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(request, ext, if_sheet_exists, msg): # GH 40230 + import openpyxl + + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and ext == ".xlsx" + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame({"fruit": ["pear"]}) with tm.ensure_clean(ext) as f: with pytest.raises(ValueError, match=re.escape(msg)): @@ -279,8 +374,21 @@ def test_if_sheet_exists_raises(ext, if_sheet_exists, msg): df.to_excel(writer, sheet_name="foo") -def test_to_excel_with_openpyxl_engine(ext): +def test_to_excel_with_openpyxl_engine(request, ext): # GH 29854 + import openpyxl + + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and ext == ".xlsx" + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) with tm.ensure_clean(ext) as filename: df1 = DataFrame({"A": np.linspace(1, 10, 10)}) @@ -338,8 +446,21 @@ def test_read_with_bad_dimension( tm.assert_frame_equal(result, expected) -def test_append_mode_file(ext): +def test_append_mode_file(request, ext): # GH 39576 + import openpyxl + + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and ext == ".xlsx" + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame() with tm.ensure_clean(ext) as f: diff --git a/pandas/tests/io/test_fsspec.py b/pandas/tests/io/test_fsspec.py index 3a575d54d9d11..e3e8358aa6340 100644 --- a/pandas/tests/io/test_fsspec.py +++ b/pandas/tests/io/test_fsspec.py @@ -293,14 +293,17 @@ def test_stata_options(fsspectest): @td.skip_if_no("tabulate") def test_markdown_options(request, fsspectest): import fsspec - import tabulate + + # error: Library stubs not installed for "tabulate" + # (or incompatible with Python 3.8) + import tabulate # type: ignore[import] request.node.add_marker( pytest.mark.xfail( fsspec.__version__ == VERSIONS["fsspec"] and tabulate.__version__ == VERSIONS["tabulate"], reason="Fails on the min version build", - raises=KeyError, + raises=FileNotFoundError, ) ) df = DataFrame({"a": [0]}) From 81fb36275ee985695603d1b31210a0dbedce30bc Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Wed, 29 Dec 2021 13:20:02 -0800 Subject: [PATCH 05/15] Add more xfails for lxml and openpyxl --- pandas/tests/io/excel/test_style.py | 47 ++++++++++-- pandas/tests/io/excel/test_writers.py | 106 +++++++++++++++++++++++--- 2 files changed, 139 insertions(+), 14 deletions(-) diff --git a/pandas/tests/io/excel/test_style.py b/pandas/tests/io/excel/test_style.py index 8a142aebd719d..409764ae2ac09 100644 --- a/pandas/tests/io/excel/test_style.py +++ b/pandas/tests/io/excel/test_style.py @@ -1,6 +1,11 @@ import numpy as np import pytest +from pandas.compat._optional import ( + VERSIONS, + import_optional_dependency, +) + from pandas import DataFrame import pandas._testing as tm @@ -27,9 +32,20 @@ def assert_equal_cell_styles(cell1, cell2): "engine", ["xlsxwriter", "openpyxl"], ) -def test_styler_to_excel_unstyled(engine): +def test_styler_to_excel_unstyled(request, engine): # compare DataFrame.to_excel and Styler.to_excel when no styles applied - pytest.importorskip(engine) + mod = pytest.importorskip(engine) + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + engine == "openpyxl", + mod.__version__ == VERSIONS["openpyxl"] + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame(np.random.randn(2, 2)) with tm.ensure_clean(".xlsx") as path: with ExcelWriter(path, engine=engine) as writer: @@ -76,8 +92,19 @@ def test_styler_to_excel_unstyled(engine): ["xlsxwriter", "openpyxl"], ) @pytest.mark.parametrize("css, attrs, expected", shared_style_params) -def test_styler_to_excel_basic(engine, css, attrs, expected): - pytest.importorskip(engine) +def test_styler_to_excel_basic(request, engine, css, attrs, expected): + mod = pytest.importorskip(engine) + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + engine == "openpyxl", + mod.__version__ == VERSIONS["openpyxl"] + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame(np.random.randn(1, 1)) styler = df.style.applymap(lambda x: css) @@ -149,8 +176,18 @@ def test_styler_to_excel_basic_indexes(engine, css, attrs, expected): assert sc_cell == expected -def test_styler_custom_converter(): +def test_styler_custom_converter(request): openpyxl = pytest.importorskip("openpyxl") + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + openpyxl.__version__ == VERSIONS["openpyxl"] + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + ) + ) def custom_converter(css): return {"font": {"color": {"rgb": "111222"}}} diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 0315783569c23..3ee7bbda2acc4 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -11,6 +11,10 @@ import numpy as np import pytest +from pandas.compat._optional import ( + VERSIONS, + import_optional_dependency, +) import pandas.util._test_decorators as td import pandas as pd @@ -33,6 +37,17 @@ ) +def has_min_lxml_and_openpyxl(): + openpyxl = import_optional_dependency("openpyxl", errors="ignore") + lxml = import_optional_dependency("lxml.etree", errors="ignore") + return ( + openpyxl is not None + and openpyxl.__version__ == VERSIONS["openpyxl"] + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"] + ) + + @pytest.fixture def path(ext): """ @@ -76,8 +91,15 @@ class TestRoundTrip: "header,expected", [(None, DataFrame([np.nan] * 4)), (0, DataFrame({"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, request, ext, header, expected): # xref gh-12292 + request.node.add_marker( + pytest.mark.xfail( + ext == ".xlsm" and has_min_lxml_and_openpyxl(), + reason="Fails on the min version build", + raises=TypeError, + ) + ) filename = "no_header" df = DataFrame([["", 1, 100], ["", 2, 200], ["", 3, 300], ["", 4, 400]]) @@ -93,7 +115,14 @@ def test_read_one_empty_col_no_header(self, ext, header, expected): "header,expected", [(None, DataFrame([0] + [np.nan] * 4)), (0, DataFrame([np.nan] * 4))], ) - def test_read_one_empty_col_with_header(self, ext, header, expected): + def test_read_one_empty_col_with_header(self, request, ext, header, expected): + request.node.add_marker( + pytest.mark.xfail( + ext == ".xlsm" and has_min_lxml_and_openpyxl(), + reason="Fails on the min version build", + raises=TypeError, + ) + ) filename = "with_header" df = DataFrame([["", 1, 100], ["", 2, 200], ["", 3, 300], ["", 4, 400]]) @@ -105,9 +134,16 @@ def test_read_one_empty_col_with_header(self, ext, header, expected): tm.assert_frame_equal(result, expected) - def test_set_column_names_in_parameter(self, ext): + def test_set_column_names_in_parameter(self, request, ext): # GH 12870 : pass down column names associated with # keyword argument names + request.node.add_marker( + pytest.mark.xfail( + ext == ".xlsm" and has_min_lxml_and_openpyxl(), + reason="Fails on the min version build", + raises=TypeError, + ) + ) refdf = DataFrame([[1, "foo"], [2, "bar"], [3, "baz"]], columns=["a", "b"]) with tm.ensure_clean(ext) as pth: @@ -131,11 +167,19 @@ def test_set_column_names_in_parameter(self, ext): 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, request, ext): # see gh-9450 # # Test reading multiple sheets, from a runtime # created Excel file with multiple sheets. + request.node.add_marker( + pytest.mark.xfail( + ext == ".xlsm" and has_min_lxml_and_openpyxl(), + reason="Fails on the min version build", + raises=TypeError, + ) + ) + def tdf(col_sheet_name): d, i = [11, 22, 33], [1, 2, 3] return DataFrame(d, i, columns=[col_sheet_name]) @@ -155,8 +199,15 @@ def tdf(col_sheet_name): 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, request, ext): # see gh-12453 + request.node.add_marker( + pytest.mark.xfail( + ext == ".xlsm" and has_min_lxml_and_openpyxl(), + reason="Fails on the min version build", + raises=TypeError, + ) + ) with tm.ensure_clean(ext) as path: df = DataFrame( { @@ -209,6 +260,13 @@ def test_read_excel_multiindex_empty_level(self, ext): def test_excel_multindex_roundtrip( self, ext, c_idx_names, r_idx_names, c_idx_levels, r_idx_levels, request ): + request.node.add_marker( + pytest.mark.xfail( + ext == ".xlsm" and has_min_lxml_and_openpyxl(), + reason="Fails on the min version build", + raises=TypeError, + ) + ) # see gh-4679 with tm.ensure_clean(ext) as pth: if (c_idx_levels == 1 and c_idx_names) and not ( @@ -255,8 +313,15 @@ def test_excel_multindex_roundtrip( ) 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, request, ext): # see gh-11544, gh-12051 + request.node.add_marker( + pytest.mark.xfail( + ext == ".xlsm" and has_min_lxml_and_openpyxl(), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame( {"col": [1, 2, 3], "date_strings": pd.date_range("2012-01-01", periods=3)} ) @@ -278,8 +343,15 @@ def test_read_excel_parse_dates(self, ext): ) tm.assert_frame_equal(df, res) - def test_multiindex_interval_datetimes(self, ext): + def test_multiindex_interval_datetimes(self, request, ext): # GH 30986 + request.node.add_marker( + pytest.mark.xfail( + ext == ".xlsm" and has_min_lxml_and_openpyxl(), + reason="Fails on the min version build", + raises=TypeError, + ) + ) midx = MultiIndex.from_arrays( [ range(4), @@ -353,7 +425,16 @@ def test_excel_sheet_size(self, path): with pytest.raises(ValueError, match=msg): col_df.to_excel(path) - def test_excel_sheet_by_name_raise(self, path, engine): + def test_excel_sheet_by_name_raise(self, path, engine, request): + request.node.add_marker( + pytest.mark.xfail( + ("xlsm" in path or "xlsx" in path) + and engine == "openpyxl" + and has_min_lxml_and_openpyxl(), + reason="Fails on the min version build", + raises=TypeError, + ) + ) gt = DataFrame(np.random.randn(10, 2)) gt.to_excel(path) @@ -366,7 +447,14 @@ def test_excel_sheet_by_name_raise(self, path, engine): with pytest.raises(ValueError, match=msg): pd.read_excel(xl, "0") - def test_excel_writer_context_manager(self, frame, path): + def test_excel_writer_context_manager(self, request, frame, path): + request.node.add_marker( + pytest.mark.xfail( + ("xlsm" in path or "xlsx" in path) and has_min_lxml_and_openpyxl(), + reason="Fails on the min version build", + raises=TypeError, + ) + ) with ExcelWriter(path) as writer: frame.to_excel(writer, "Data1") frame2 = frame.copy() From 89bdf9a91ae4a819d6981cff2f08b07e88899001 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Wed, 29 Dec 2021 18:44:22 -0800 Subject: [PATCH 06/15] Hopefully last of the xfails --- pandas/tests/io/excel/test_style.py | 18 +- pandas/tests/io/excel/test_writers.py | 436 ++++++++++++++++++++++---- 2 files changed, 396 insertions(+), 58 deletions(-) diff --git a/pandas/tests/io/excel/test_style.py b/pandas/tests/io/excel/test_style.py index 409764ae2ac09..a01ee2fcd1fdf 100644 --- a/pandas/tests/io/excel/test_style.py +++ b/pandas/tests/io/excel/test_style.py @@ -44,6 +44,7 @@ def test_styler_to_excel_unstyled(request, engine): and lxml.__version__ == VERSIONS["lxml.etree"], reason="Fails on the min version build", raises=TypeError, + strict=False, # But passes on other builds ) ) df = DataFrame(np.random.randn(2, 2)) @@ -103,6 +104,7 @@ def test_styler_to_excel_basic(request, engine, css, attrs, expected): and lxml.__version__ == VERSIONS["lxml.etree"], reason="Fails on the min version build", raises=TypeError, + strict=False, # But passes on other builds ) ) df = DataFrame(np.random.randn(1, 1)) @@ -135,8 +137,20 @@ def test_styler_to_excel_basic(request, engine, css, attrs, expected): ["xlsxwriter", "openpyxl"], ) @pytest.mark.parametrize("css, attrs, expected", shared_style_params) -def test_styler_to_excel_basic_indexes(engine, css, attrs, expected): - pytest.importorskip(engine) +def test_styler_to_excel_basic_indexes(request, engine, css, attrs, expected): + mod = pytest.importorskip(engine) + lxml = import_optional_dependency("lxml.etree", errors="ignore") + request.node.add_marker( + pytest.mark.xfail( + engine == "openpyxl", + mod.__version__ == VERSIONS["openpyxl"] + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"], + reason="Fails on the min version build", + raises=TypeError, + strict=False, # But passes on other builds + ) + ) df = DataFrame(np.random.randn(1, 1)) styler = df.style diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 3ee7bbda2acc4..044fe06dcb7c6 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -48,6 +48,10 @@ def has_min_lxml_and_openpyxl(): ) +def xlsx_xlsm_fails(path): + return ("xlsm" in path or "xlsx" in path) and has_min_lxml_and_openpyxl() + + @pytest.fixture def path(ext): """ @@ -428,9 +432,7 @@ def test_excel_sheet_size(self, path): def test_excel_sheet_by_name_raise(self, path, engine, request): request.node.add_marker( pytest.mark.xfail( - ("xlsm" in path or "xlsx" in path) - and engine == "openpyxl" - and has_min_lxml_and_openpyxl(), + xlsx_xlsm_fails(path) and engine == "openpyxl", reason="Fails on the min version build", raises=TypeError, ) @@ -448,9 +450,12 @@ def test_excel_sheet_by_name_raise(self, path, engine, request): pd.read_excel(xl, "0") def test_excel_writer_context_manager(self, request, frame, path): + option_name = f"io.excel.{path.split('.')[-1]}.writer" + curr_engine = get_option(option_name) + xlsxwriter_and_xlsx = curr_engine == "xlsxwriter" and "xlsx" in path request.node.add_marker( pytest.mark.xfail( - ("xlsm" in path or "xlsx" in path) and has_min_lxml_and_openpyxl(), + xlsx_xlsm_fails(path) and not xlsxwriter_and_xlsx, reason="Fails on the min version build", raises=TypeError, ) @@ -468,7 +473,14 @@ def test_excel_writer_context_manager(self, request, frame, path): tm.assert_frame_equal(found_df, frame) tm.assert_frame_equal(found_df2, frame2) - def test_roundtrip(self, frame, path): + def test_roundtrip(self, request, frame, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) frame = frame.copy() frame["A"][:5] = np.nan @@ -517,7 +529,14 @@ def test_roundtrip(self, frame, path): recons = pd.read_excel(path, index_col=0) tm.assert_frame_equal(s.to_frame(), recons) - def test_mixed(self, frame, path): + def test_mixed(self, request, frame, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) mixed_frame = frame.copy() mixed_frame["foo"] = "bar" @@ -526,7 +545,14 @@ def test_mixed(self, frame, path): recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(mixed_frame, recons) - def test_ts_frame(self, tsframe, path): + def test_ts_frame(self, request, tsframe, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = tsframe # freq doesn't round-trip @@ -538,7 +564,14 @@ def test_ts_frame(self, tsframe, path): recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(df, recons) - def test_basics_with_nan(self, frame, path): + def test_basics_with_nan(self, request, frame, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) frame = frame.copy() frame["A"][:5] = np.nan frame.to_excel(path, "test1") @@ -547,7 +580,14 @@ def test_basics_with_nan(self, frame, path): frame.to_excel(path, "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, request, np_type, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) # Test np.int values read come back as int # (rather than float which is Excel's format). df = DataFrame(np.random.randint(-10, 10, size=(10, 2)), dtype=np_type) @@ -575,7 +615,14 @@ def test_int_types(self, np_type, path): tm.assert_frame_equal(recons, float_frame) @pytest.mark.parametrize("np_type", [np.float16, np.float32, np.float64]) - def test_float_types(self, np_type, path): + def test_float_types(self, request, np_type, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) # Test np.float values read come back as float. df = DataFrame(np.random.random_sample(10), dtype=np_type) df.to_excel(path, "test1") @@ -588,7 +635,14 @@ def test_float_types(self, np_type, path): tm.assert_frame_equal(df, recons) @pytest.mark.parametrize("np_type", [np.bool8, np.bool_]) - def test_bool_types(self, np_type, path): + def test_bool_types(self, request, np_type, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) # Test np.bool8 and np.bool_ values read come back as float. df = DataFrame([1, 0, True, False], dtype=np_type) df.to_excel(path, "test1") @@ -600,7 +654,14 @@ def test_bool_types(self, np_type, path): tm.assert_frame_equal(df, recons) - def test_inf_roundtrip(self, path): + def test_inf_roundtrip(self, request, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame([(1, np.inf), (2, 3), (5, -np.inf)]) df.to_excel(path, "test1") @@ -609,8 +670,14 @@ def test_inf_roundtrip(self, path): tm.assert_frame_equal(df, recons) - def test_sheets(self, frame, tsframe, path): - + def test_sheets(self, request, frame, tsframe, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) # freq doesn't round-trip index = pd.DatetimeIndex(np.asarray(tsframe.index), freq=None) tsframe.index = index @@ -636,7 +703,14 @@ def test_sheets(self, frame, tsframe, path): assert "test1" == reader.sheet_names[0] assert "test2" == reader.sheet_names[1] - def test_colaliases(self, frame, path): + def test_colaliases(self, request, frame, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) frame = frame.copy() frame["A"][:5] = np.nan @@ -654,7 +728,14 @@ def test_colaliases(self, frame, path): xp.columns = col_aliases tm.assert_frame_equal(xp, rs) - def test_roundtrip_indexlabels(self, merge_cells, frame, path): + def test_roundtrip_indexlabels(self, request, merge_cells, frame, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) frame = frame.copy() frame["A"][:5] = np.nan @@ -711,7 +792,14 @@ def test_roundtrip_indexlabels(self, merge_cells, frame, path): 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, request, merge_cells, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame(np.random.randn(10, 4)) df.index.name = "foo" @@ -723,10 +811,17 @@ def test_excel_roundtrip_indexname(self, merge_cells, path): tm.assert_frame_equal(result, df) assert result.index.name == "foo" - def test_excel_roundtrip_datetime(self, merge_cells, tsframe, path): + def test_excel_roundtrip_datetime(self, request, merge_cells, tsframe, path): # datetime.date, not sure what to test here exactly # freq does not round-trip + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) index = pd.DatetimeIndex(np.asarray(tsframe.index), freq=None) tsframe.index = index @@ -740,10 +835,17 @@ def test_excel_roundtrip_datetime(self, merge_cells, tsframe, path): tm.assert_frame_equal(tsframe, recons) - def test_excel_date_datetime_format(self, engine, ext, path): + def test_excel_date_datetime_format(self, request, engine, ext, path): # see gh-4133 # # Excel output format strings + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame( [ [date(2014, 1, 31), date(1999, 9, 24)], @@ -784,10 +886,17 @@ def test_excel_date_datetime_format(self, engine, 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): + def test_to_excel_interval_no_labels(self, request, path): # see gh-19242 # # Test writing Interval without labels. + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame(np.random.randint(-10, 10, size=(20, 1)), dtype=np.int64) expected = df.copy() @@ -799,10 +908,17 @@ def test_to_excel_interval_no_labels(self, path): 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, request, path): # see gh-19242 # # Test writing Interval with labels. + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame(np.random.randint(-10, 10, size=(20, 1)), dtype=np.int64) expected = df.copy() intervals = pd.cut( @@ -816,10 +932,17 @@ def test_to_excel_interval_labels(self, path): 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, request, path): # see gh-19242, gh-9155 # # Test writing timedelta to xls. + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame( np.random.randint(-10, 10, size=(20, 1)), columns=["A"], dtype=np.int64 ) @@ -835,7 +958,14 @@ def test_to_excel_timedelta(self, path): recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(expected, recons) - def test_to_excel_periodindex(self, tsframe, path): + def test_to_excel_periodindex(self, request, tsframe, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) xp = tsframe.resample("M", kind="period").mean() xp.to_excel(path, "sht1") @@ -844,7 +974,14 @@ def test_to_excel_periodindex(self, tsframe, path): 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, request, merge_cells, frame, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) arrays = np.arange(len(frame.index) * 2).reshape(2, -1) new_index = MultiIndex.from_arrays(arrays, names=["first", "second"]) frame.index = new_index @@ -859,7 +996,14 @@ def test_to_excel_multiindex(self, merge_cells, frame, path): 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, request, merge_cells, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame({"A": [None, 2, 3], "B": [10, 20, 30], "C": np.random.sample(3)}) df = df.set_index(["A", "B"]) @@ -870,7 +1014,14 @@ def test_to_excel_multiindex_nan_label(self, merge_cells, path): # 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, request, merge_cells, frame, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) arrays = np.arange(len(frame.index) * 2).reshape(2, -1) new_index = MultiIndex.from_arrays(arrays, names=["first", "second"]) frame.index = new_index @@ -892,8 +1043,15 @@ 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, tsframe, path): + def test_to_excel_multiindex_dates(self, request, merge_cells, tsframe, path): # try multiindex with dates + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) new_index = [tsframe.index, np.arange(len(tsframe.index))] tsframe.index = MultiIndex.from_arrays(new_index) @@ -905,8 +1063,15 @@ def test_to_excel_multiindex_dates(self, merge_cells, tsframe, path): 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, request, path): # Test writing and re-reading a MI without the index. GH 5616. + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) # Initial non-MI frame. frame1 = DataFrame({"a": [10, 20], "b": [30, 40], "c": [50, 60]}) @@ -926,7 +1091,14 @@ def test_to_excel_multiindex_no_write_index(self, path): # Test that it is the same as the initial frame. tm.assert_frame_equal(frame1, frame3) - def test_to_excel_float_format(self, path): + def test_to_excel_float_format(self, request, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame( [[0.123456, 0.234567, 0.567567], [12.32112, 123123.2, 321321.2]], index=["A", "B"], @@ -944,7 +1116,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, request, ext): # Avoid mixed inferred_type. df = DataFrame( [["\u0192", "\u0193", "\u0194"], ["\u0195", "\u0196", "\u0197"]], @@ -953,11 +1125,25 @@ def test_to_excel_output_encoding(self, ext): ) with tm.ensure_clean("__tmp_to_excel_float_format__." + ext) as filename: + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(filename), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df.to_excel(filename, sheet_name="TestSheet", encoding="utf8") 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, path): + def test_to_excel_unicode_filename(self, request, ext, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) with tm.ensure_clean("\u0192u." + ext) as filename: try: f = open(filename, "wb") @@ -987,8 +1173,16 @@ def test_to_excel_unicode_filename(self, ext, path): @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, request, merge_cells, c_idx_nlevels, r_idx_nlevels, use_headers, path ): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) + def roundtrip(data, header=True, parser_hdr=0, index=True): data.to_excel(path, header=header, merge_cells=merge_cells, index=index) @@ -1038,8 +1232,15 @@ 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, request, path): # see gh-5235 + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame([[1, 2, 3], [1, 2, 3], [1, 2, 3]], columns=["A", "B", "B"]) df.to_excel(path, "test1") expected = DataFrame( @@ -1077,8 +1278,15 @@ def test_duplicated_columns(self, path): with pytest.raises(ValueError, match=msg): pd.read_excel(path, sheet_name="test1", header=None, mangle_dupe_cols=False) - def test_swapped_columns(self, path): + def test_swapped_columns(self, request, path): # Test for issue #5427. + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) write_frame = DataFrame({"A": [1, 1, 1], "B": [2, 2, 2]}) write_frame.to_excel(path, "test1", columns=["B", "A"]) @@ -1106,8 +1314,17 @@ 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, request, path, to_excel_index, read_excel_index_col + ): # GH 31677 + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) write_frame = DataFrame({"A": [1, 1, 1], "B": [2, 2, 2], "C": [3, 3, 3]}) write_frame.to_excel( path, "col_subset_bug", columns=["A", "B"], index=to_excel_index @@ -1120,11 +1337,17 @@ def test_write_subset_columns(self, path, to_excel_index, read_excel_index_col): tm.assert_frame_equal(expected, read_frame) - def test_comment_arg(self, path): + def test_comment_arg(self, request, path): # see gh-18735 # # Test the comment argument functionality to pd.read_excel. - + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) # Create file to read in. df = DataFrame({"A": ["one", "#one", "one"], "B": ["two", "two", "#two"]}) df.to_excel(path, "test_c") @@ -1139,10 +1362,16 @@ def test_comment_arg(self, path): result2 = pd.read_excel(path, 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, request, path): # Re issue #18735 # Test the comment argument default to pd.read_excel - + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) # Create file to read in df = DataFrame({"A": ["one", "#one", "one"], "B": ["two", "two", "#two"]}) df.to_excel(path, "test_c") @@ -1152,11 +1381,17 @@ def test_comment_default(self, path): result2 = pd.read_excel(path, sheet_name="test_c", comment=None) tm.assert_frame_equal(result1, result2) - def test_comment_used(self, path): + def test_comment_used(self, request, path): # see gh-18735 # # Test the comment argument is working as expected when used. - + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) # Create file to read in. df = DataFrame({"A": ["one", "#one", "one"], "B": ["two", "two", "#two"]}) df.to_excel(path, "test_c") @@ -1166,10 +1401,16 @@ def test_comment_used(self, path): result = pd.read_excel(path, 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, request, path): # Re issue #18735 # Test that pd.read_excel ignores commented lines at the end of file - + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame({"a": ["1", "#2"], "b": ["2", "3"]}) df.to_excel(path, index=False) @@ -1178,8 +1419,14 @@ def test_comment_empty_line(self, path): result = pd.read_excel(path, comment="#") tm.assert_frame_equal(result, expected) - def test_datetimes(self, path): - + def test_datetimes(self, request, path): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) # Test writing and reading datetimes. For issue #9139. (xref #9185) datetimes = [ datetime(2013, 1, 13, 1, 2, 3), @@ -1206,8 +1453,15 @@ def test_datetimes(self, path): tm.assert_series_equal(write_frame["A"], read_frame["A"]) - def test_bytes_io(self, engine): + def test_bytes_io(self, request, engine): # see gh-7074 + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) with BytesIO() as bio: df = DataFrame(np.random.randn(10, 2)) @@ -1219,8 +1473,15 @@ def test_bytes_io(self, engine): reread_df = pd.read_excel(bio, index_col=0) tm.assert_frame_equal(df, reread_df) - def test_write_lists_dict(self, path): + def test_write_lists_dict(self, request, path): # see gh-8188. + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame( { "mixed": ["a", ["b", "c"], {"d": "e", "f": 2}], @@ -1237,16 +1498,30 @@ 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, request, path): # see gh-34331 + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame({"render": [1, 2], "data": [3, 4]}) df.to_excel(path, "Sheet1") read = pd.read_excel(path, "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, request, path): # see gh-13347 + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame([["foo", "bar"]], columns=["col1", "col2"]) expected = df.replace({"foo": True, "bar": False}) @@ -1256,15 +1531,29 @@ def test_true_and_false_value_options(self, path): ) tm.assert_frame_equal(read_frame, expected) - def test_freeze_panes(self, path): + def test_freeze_panes(self, request, path): # see gh-15160 + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) expected = DataFrame([[1, 2], [3, 4]], columns=["col1", "col2"]) expected.to_excel(path, "Sheet1", freeze_panes=(1, 1)) result = pd.read_excel(path, index_col=0) tm.assert_frame_equal(result, expected) - def test_path_path_lib(self, engine, ext): + def test_path_path_lib(self, request, engine, ext): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(ext), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = tm.makeDataFrame() writer = partial(df.to_excel, engine=engine) @@ -1272,7 +1561,14 @@ 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_path_local_path(self, engine, ext): + def test_path_local_path(self, request, engine, ext): + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(ext), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = tm.makeDataFrame() writer = partial(df.to_excel, engine=engine) @@ -1280,8 +1576,15 @@ def test_path_local_path(self, engine, ext): result = tm.round_trip_localpath(writer, reader, path=f"foo{ext}") tm.assert_frame_equal(result, df) - def test_merged_cell_custom_objects(self, merge_cells, path): + def test_merged_cell_custom_objects(self, request, merge_cells, path): # see GH-27006 + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) mi = MultiIndex.from_tuples( [ (pd.Period("2018"), pd.Period("2018Q1")), @@ -1290,8 +1593,15 @@ def test_merged_cell_custom_objects(self, merge_cells, path): ) expected = DataFrame(np.ones((2, 2)), columns=mi) expected.to_excel(path) + option_name = f"io.excel.{path.split('.')[-1]}.writer" + curr_engine = get_option(option_name) + xlsxwriter_and_xlsx_produces_resourcewarnings = ( + curr_engine == "xlsxwriter" and "xlsx" in path + ) with tm.assert_produces_warning( - FutureWarning, match="convert_float is deprecated" + FutureWarning, + match="convert_float is deprecated", + raise_on_extra_warnings=not xlsxwriter_and_xlsx_produces_resourcewarnings, ): result = pd.read_excel( path, header=[0, 1], index_col=0, convert_float=False @@ -1305,8 +1615,15 @@ def test_merged_cell_custom_objects(self, merge_cells, path): tm.assert_frame_equal(expected, result) @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, request, dtype, tz_aware_fixture, path): # GH 27008, GH 7056 + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) tz = tz_aware_fixture data = pd.Timestamp("2019", tz=tz) df = DataFrame([data], dtype=dtype) @@ -1318,8 +1635,15 @@ def test_raise_when_saving_timezones(self, dtype, tz_aware_fixture, path): with pytest.raises(ValueError, match="Excel does not support"): df.to_excel(path) - def test_excel_duplicate_columns_with_names(self, path): + def test_excel_duplicate_columns_with_names(self, request, path): # GH#39695 + request.node.add_marker( + pytest.mark.xfail( + xlsx_xlsm_fails(path), + reason="Fails on the min version build", + raises=TypeError, + ) + ) df = DataFrame({"A": [0, 1], "B": [10, 11]}) df.to_excel(path, columns=["A", "B", "A"], index=False) From 0295f696293d5c87bf8cbd45622fe9981653eb14 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Wed, 29 Dec 2021 21:11:49 -0800 Subject: [PATCH 07/15] Fix func input --- pandas/tests/io/excel/test_writers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 044fe06dcb7c6..b429249a9fb4f 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -1455,9 +1455,10 @@ def test_datetimes(self, request, path): def test_bytes_io(self, request, engine): # see gh-7074 + ext = request.getfixturevalue("ext") request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + xlsx_xlsm_fails(ext), reason="Fails on the min version build", raises=TypeError, ) From d7b796c386a0fa9a04f5922f8878db8f5dd01bb8 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Thu, 30 Dec 2021 10:17:44 -0800 Subject: [PATCH 08/15] xpass for xlswriter --- pandas/tests/io/excel/test_writers.py | 145 +++++++++++++------- pandas/tests/series/methods/test_reindex.py | 4 - 2 files changed, 97 insertions(+), 52 deletions(-) diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index b429249a9fb4f..c12c639c97cfd 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -48,10 +48,14 @@ def has_min_lxml_and_openpyxl(): ) -def xlsx_xlsm_fails(path): +def openpyxl_installed_and_xlsx_xlsm(path): return ("xlsm" in path or "xlsx" in path) and has_min_lxml_and_openpyxl() +def xlswriter_and_xlsx(path, engine): + return "xlsx" in path and engine == "xlsxwriter" + + @pytest.fixture def path(ext): """ @@ -432,7 +436,7 @@ def test_excel_sheet_size(self, path): def test_excel_sheet_by_name_raise(self, path, engine, request): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path) and engine == "openpyxl", + openpyxl_installed_and_xlsx_xlsm(path) and engine == "openpyxl", reason="Fails on the min version build", raises=TypeError, ) @@ -455,7 +459,7 @@ def test_excel_writer_context_manager(self, request, frame, path): xlsxwriter_and_xlsx = curr_engine == "xlsxwriter" and "xlsx" in path request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path) and not xlsxwriter_and_xlsx, + openpyxl_installed_and_xlsx_xlsm(path) and not xlsxwriter_and_xlsx, reason="Fails on the min version build", raises=TypeError, ) @@ -476,7 +480,8 @@ def test_excel_writer_context_manager(self, request, frame, path): def test_roundtrip(self, request, frame, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -532,7 +537,8 @@ def test_roundtrip(self, request, frame, path): def test_mixed(self, request, frame, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -548,7 +554,8 @@ def test_mixed(self, request, frame, path): def test_ts_frame(self, request, tsframe, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -567,7 +574,8 @@ def test_ts_frame(self, request, tsframe, path): def test_basics_with_nan(self, request, frame, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -583,7 +591,8 @@ def test_basics_with_nan(self, request, frame, path): def test_int_types(self, request, np_type, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -618,7 +627,8 @@ def test_int_types(self, request, np_type, path): def test_float_types(self, request, np_type, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -638,7 +648,8 @@ def test_float_types(self, request, np_type, path): def test_bool_types(self, request, np_type, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -657,7 +668,8 @@ def test_bool_types(self, request, np_type, path): def test_inf_roundtrip(self, request, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -673,7 +685,8 @@ def test_inf_roundtrip(self, request, path): def test_sheets(self, request, frame, tsframe, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -706,7 +719,8 @@ def test_sheets(self, request, frame, tsframe, path): def test_colaliases(self, request, frame, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -731,7 +745,8 @@ def test_colaliases(self, request, frame, path): def test_roundtrip_indexlabels(self, request, merge_cells, frame, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -795,7 +810,8 @@ def test_roundtrip_indexlabels(self, request, merge_cells, frame, path): def test_excel_roundtrip_indexname(self, request, merge_cells, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -817,7 +833,8 @@ def test_excel_roundtrip_datetime(self, request, merge_cells, tsframe, path): # freq does not round-trip request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -841,7 +858,8 @@ def test_excel_date_datetime_format(self, request, engine, ext, path): # Excel output format strings request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -892,7 +910,8 @@ def test_to_excel_interval_no_labels(self, request, path): # Test writing Interval without labels. request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -914,7 +933,8 @@ def test_to_excel_interval_labels(self, request, path): # Test writing Interval with labels. request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -938,7 +958,8 @@ def test_to_excel_timedelta(self, request, path): # Test writing timedelta to xls. request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -961,7 +982,8 @@ def test_to_excel_timedelta(self, request, path): def test_to_excel_periodindex(self, request, tsframe, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -977,7 +999,8 @@ def test_to_excel_periodindex(self, request, tsframe, path): def test_to_excel_multiindex(self, request, merge_cells, frame, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -999,7 +1022,8 @@ def test_to_excel_multiindex(self, request, merge_cells, frame, path): def test_to_excel_multiindex_nan_label(self, request, merge_cells, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1017,7 +1041,8 @@ def test_to_excel_multiindex_nan_label(self, request, merge_cells, path): def test_to_excel_multiindex_cols(self, request, merge_cells, frame, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1047,7 +1072,8 @@ def test_to_excel_multiindex_dates(self, request, merge_cells, tsframe, path): # try multiindex with dates request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1067,7 +1093,8 @@ def test_to_excel_multiindex_no_write_index(self, request, path): # Test writing and re-reading a MI without the index. GH 5616. request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1094,7 +1121,8 @@ def test_to_excel_multiindex_no_write_index(self, request, path): def test_to_excel_float_format(self, request, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1127,7 +1155,10 @@ def test_to_excel_output_encoding(self, request, ext): with tm.ensure_clean("__tmp_to_excel_float_format__." + ext) as filename: request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(filename), + openpyxl_installed_and_xlsx_xlsm(filename) + and not xlswriter_and_xlsx( + filename, request.getfixturevalue("engine") + ), reason="Fails on the min version build", raises=TypeError, ) @@ -1139,7 +1170,8 @@ def test_to_excel_output_encoding(self, request, ext): def test_to_excel_unicode_filename(self, request, ext, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1177,7 +1209,8 @@ def test_excel_010_hemstring( ): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1236,7 +1269,8 @@ def test_duplicated_columns(self, request, path): # see gh-5235 request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1282,7 +1316,8 @@ def test_swapped_columns(self, request, path): # Test for issue #5427. request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1320,7 +1355,8 @@ def test_write_subset_columns( # GH 31677 request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1343,7 +1379,8 @@ def test_comment_arg(self, request, path): # Test the comment argument functionality to pd.read_excel. request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1367,7 +1404,8 @@ def test_comment_default(self, request, path): # Test the comment argument default to pd.read_excel request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1387,7 +1425,8 @@ def test_comment_used(self, request, path): # Test the comment argument is working as expected when used. request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1406,7 +1445,8 @@ def test_comment_empty_line(self, request, path): # Test that pd.read_excel ignores commented lines at the end of file request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1422,7 +1462,7 @@ def test_comment_empty_line(self, request, path): def test_datetimes(self, request, path): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path), reason="Fails on the min version build", raises=TypeError, ) @@ -1458,7 +1498,8 @@ def test_bytes_io(self, request, engine): ext = request.getfixturevalue("ext") request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(ext), + openpyxl_installed_and_xlsx_xlsm(ext) + and not xlswriter_and_xlsx(ext, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1478,7 +1519,8 @@ def test_write_lists_dict(self, request, path): # see gh-8188. request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1503,7 +1545,8 @@ def test_render_as_column_name(self, request, path): # see gh-34331 request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1518,7 +1561,8 @@ def test_true_and_false_value_options(self, request, path): # see gh-13347 request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1536,7 +1580,8 @@ def test_freeze_panes(self, request, path): # see gh-15160 request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1550,7 +1595,8 @@ def test_freeze_panes(self, request, path): def test_path_path_lib(self, request, engine, ext): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(ext), + openpyxl_installed_and_xlsx_xlsm(ext) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1565,7 +1611,8 @@ def test_path_path_lib(self, request, engine, ext): def test_path_local_path(self, request, engine, ext): request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(ext), + openpyxl_installed_and_xlsx_xlsm(ext) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1581,7 +1628,8 @@ def test_merged_cell_custom_objects(self, request, merge_cells, path): # see GH-27006 request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1620,7 +1668,8 @@ def test_raise_when_saving_timezones(self, request, dtype, tz_aware_fixture, pat # GH 27008, GH 7056 request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1640,7 +1689,7 @@ def test_excel_duplicate_columns_with_names(self, request, path): # GH#39695 request.node.add_marker( pytest.mark.xfail( - xlsx_xlsm_fails(path), + openpyxl_installed_and_xlsx_xlsm(path), reason="Fails on the min version build", raises=TypeError, ) diff --git a/pandas/tests/series/methods/test_reindex.py b/pandas/tests/series/methods/test_reindex.py index 4350a5d9ac989..a500252a44e07 100644 --- a/pandas/tests/series/methods/test_reindex.py +++ b/pandas/tests/series/methods/test_reindex.py @@ -171,10 +171,6 @@ def test_reindex_nearest(): tm.assert_series_equal(expected, result) -def test_reindex_backfill(): - pass - - def test_reindex_int(datetime_series): ts = datetime_series[::2] int_ts = Series(np.zeros(len(ts), dtype=int), index=ts.index) From 426233f7fd4f75dad756e534a186083ed1e58d7d Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Thu, 30 Dec 2021 13:57:19 -0800 Subject: [PATCH 09/15] Fix some of the marks --- pandas/tests/io/excel/test_writers.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index c12c639c97cfd..0053597a74af8 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -1596,7 +1596,7 @@ def test_path_path_lib(self, request, engine, ext): request.node.add_marker( pytest.mark.xfail( openpyxl_installed_and_xlsx_xlsm(ext) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), + and not xlswriter_and_xlsx(ext, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1612,7 +1612,7 @@ def test_path_local_path(self, request, engine, ext): request.node.add_marker( pytest.mark.xfail( openpyxl_installed_and_xlsx_xlsm(ext) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), + and not xlswriter_and_xlsx(ext, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) @@ -1689,7 +1689,8 @@ def test_excel_duplicate_columns_with_names(self, request, path): # GH#39695 request.node.add_marker( pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path), + openpyxl_installed_and_xlsx_xlsm(path) + and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), reason="Fails on the min version build", raises=TypeError, ) From fe25d32005559b1c802193cbc849fd2748f2e252 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Thu, 30 Dec 2021 16:55:31 -0800 Subject: [PATCH 10/15] Try using helper function in test_openpyxl --- pandas/tests/io/excel/test_openpyxl.py | 95 +++++++------------------- 1 file changed, 25 insertions(+), 70 deletions(-) diff --git a/pandas/tests/io/excel/test_openpyxl.py b/pandas/tests/io/excel/test_openpyxl.py index 2bf55ea48bbdb..923bcdbf9c091 100644 --- a/pandas/tests/io/excel/test_openpyxl.py +++ b/pandas/tests/io/excel/test_openpyxl.py @@ -23,6 +23,21 @@ pytestmark = pytest.mark.parametrize("ext", [".xlsx"]) +def has_min_lxml_and_openpyxl(): + openpyxl = import_optional_dependency("openpyxl", errors="ignore") + lxml = import_optional_dependency("lxml.etree", errors="ignore") + return ( + openpyxl is not None + and openpyxl.__version__ == VERSIONS["openpyxl"] + and lxml is not None + and lxml.__version__ == VERSIONS["lxml.etree"] + ) + + +def openpyxl_installed_and_xlsx_xlsm(path): + return ("xlsm" in path or "xlsx" in path) and has_min_lxml_and_openpyxl() + + def test_to_excel_styleconverter(ext): from openpyxl import styles @@ -57,17 +72,11 @@ def test_to_excel_styleconverter(ext): def test_write_cells_merge_styled(request, ext): - import openpyxl - from pandas.io.formats.excel import ExcelCell - lxml = import_optional_dependency("lxml.etree", errors="ignore") request.node.add_marker( pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and ext == ".xlsx" - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], + openpyxl_installed_and_xlsx_xlsm(ext), reason="Fails on the min version build", raises=TypeError, ) @@ -106,15 +115,9 @@ def test_write_cells_merge_styled(request, ext): @pytest.mark.parametrize("iso_dates", [True, False]) def test_kwargs(request, ext, iso_dates): # GH 42286 GH 43445 - import openpyxl - - lxml = import_optional_dependency("lxml.etree", errors="ignore") request.node.add_marker( pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and ext == ".xlsx" - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], + openpyxl_installed_and_xlsx_xlsm(ext), reason="Fails on the min version build", raises=TypeError, ) @@ -132,15 +135,9 @@ def test_kwargs(request, ext, iso_dates): @pytest.mark.parametrize("iso_dates", [True, False]) def test_engine_kwargs_write(request, ext, iso_dates): # GH 42286 GH 43445 - import openpyxl - - lxml = import_optional_dependency("lxml.etree", errors="ignore") request.node.add_marker( pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and ext == ".xlsx" - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], + openpyxl_installed_and_xlsx_xlsm(ext), reason="Fails on the min version build", raises=TypeError, ) @@ -176,15 +173,9 @@ def test_engine_kwargs_append_data_only(request, ext, data_only, expected): # GH 43445 # tests whether the data_only engine_kwarg actually works well for # openpyxl's load_workbook - import openpyxl - - lxml = import_optional_dependency("lxml.etree", errors="ignore") request.node.add_marker( pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and ext == ".xlsx" - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], + openpyxl_installed_and_xlsx_xlsm(ext), reason="Fails on the min version build", raises=TypeError, ) @@ -203,15 +194,9 @@ def test_engine_kwargs_append_data_only(request, ext, data_only, expected): "mode,expected", [("w", ["baz"]), ("a", ["foo", "bar", "baz"])] ) def test_write_append_mode(request, ext, mode, expected): - import openpyxl - - lxml = import_optional_dependency("lxml.etree", errors="ignore") request.node.add_marker( pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and ext == ".xlsx" - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], + openpyxl_installed_and_xlsx_xlsm(ext), reason="Fails on the min version build", raises=TypeError, ) @@ -249,15 +234,9 @@ def test_if_sheet_exists_append_modes( request, ext, if_sheet_exists, num_sheets, expected ): # GH 40230 - import openpyxl - - lxml = import_optional_dependency("lxml.etree", errors="ignore") request.node.add_marker( pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and ext == ".xlsx" - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], + openpyxl_installed_and_xlsx_xlsm(ext), reason="Fails on the min version build", raises=TypeError, ) @@ -295,15 +274,9 @@ def test_if_sheet_exists_append_modes( def test_append_overlay_startrow_startcol( request, ext, startrow, startcol, greeting, goodbye ): - import openpyxl - - lxml = import_optional_dependency("lxml.etree", errors="ignore") request.node.add_marker( pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and ext == ".xlsx" - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], + openpyxl_installed_and_xlsx_xlsm(ext), reason="Fails on the min version build", raises=TypeError, ) @@ -351,15 +324,9 @@ def test_append_overlay_startrow_startcol( ) def test_if_sheet_exists_raises(request, ext, if_sheet_exists, msg): # GH 40230 - import openpyxl - - lxml = import_optional_dependency("lxml.etree", errors="ignore") request.node.add_marker( pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and ext == ".xlsx" - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], + openpyxl_installed_and_xlsx_xlsm(ext), reason="Fails on the min version build", raises=TypeError, ) @@ -376,15 +343,9 @@ def test_if_sheet_exists_raises(request, ext, if_sheet_exists, msg): def test_to_excel_with_openpyxl_engine(request, ext): # GH 29854 - import openpyxl - - lxml = import_optional_dependency("lxml.etree", errors="ignore") request.node.add_marker( pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and ext == ".xlsx" - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], + openpyxl_installed_and_xlsx_xlsm(ext), reason="Fails on the min version build", raises=TypeError, ) @@ -448,15 +409,9 @@ def test_read_with_bad_dimension( def test_append_mode_file(request, ext): # GH 39576 - import openpyxl - - lxml = import_optional_dependency("lxml.etree", errors="ignore") request.node.add_marker( pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and ext == ".xlsx" - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], + openpyxl_installed_and_xlsx_xlsm(ext), reason="Fails on the min version build", raises=TypeError, ) From f703d55a97df9496508bb11cb57b2bce8d3ad0a3 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Thu, 30 Dec 2021 22:15:48 -0800 Subject: [PATCH 11/15] Bump openpyxl to fix lxml compat issue --- ci/deps/actions-38-minimum_versions.yaml | 2 +- doc/source/getting_started/install.rst | 2 +- doc/source/whatsnew/v1.4.0.rst | 2 +- pandas/compat/_optional.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ci/deps/actions-38-minimum_versions.yaml b/ci/deps/actions-38-minimum_versions.yaml index 6ea9efc8833e2..8505dad542239 100644 --- a/ci/deps/actions-38-minimum_versions.yaml +++ b/ci/deps/actions-38-minimum_versions.yaml @@ -32,7 +32,7 @@ dependencies: - matplotlib=3.3.2 - numba=0.50.1 - numexpr=2.7.1 - - openpyxl=3.0.2 + - openpyxl=3.0.3 - odfpy=1.4.1 - pandas-gbq=0.14.0 - psycopg2=2.8.4 diff --git a/doc/source/getting_started/install.rst b/doc/source/getting_started/install.rst index 28b9da137e86d..05c47d5cdf4f7 100644 --- a/doc/source/getting_started/install.rst +++ b/doc/source/getting_started/install.rst @@ -291,7 +291,7 @@ Dependency Minimum Version Notes xlrd 2.0.1 Reading Excel xlwt 1.3.0 Writing Excel xlsxwriter 1.2.2 Writing Excel -openpyxl 3.0.2 Reading / writing for xlsx files +openpyxl 3.0.3 Reading / writing for xlsx files pyxlsb 1.0.6 Reading for xlsb files ========================= ================== ============================================================= diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index 3924191bebcfd..29219c5db9fbe 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -442,7 +442,7 @@ Optional libraries below the lowest tested version may still work, but are not c +-----------------+-----------------+---------+ | numba | 0.50.1 | X | +-----------------+-----------------+---------+ -| openpyxl | 3.0.2 | X | +| openpyxl | 3.0.3 | X | +-----------------+-----------------+---------+ | pyarrow | 1.0.1 | X | +-----------------+-----------------+---------+ diff --git a/pandas/compat/_optional.py b/pandas/compat/_optional.py index c3b7cfa3e0026..a2be663504abe 100644 --- a/pandas/compat/_optional.py +++ b/pandas/compat/_optional.py @@ -19,7 +19,7 @@ "matplotlib": "3.3.2", "numexpr": "2.7.1", "odfpy": "1.4.1", - "openpyxl": "3.0.2", + "openpyxl": "3.0.3", "pandas_gbq": "0.14.0", "pyarrow": "1.0.1", "pytest": "6.0", From b4932c158e08d5844a8289c422a7719a911c4a68 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Fri, 31 Dec 2021 16:30:56 -0800 Subject: [PATCH 12/15] Revert excel xfails; see what fails now --- pandas/tests/io/excel/test_openpyxl.py | 114 +---- pandas/tests/io/excel/test_style.py | 65 +-- pandas/tests/io/excel/test_writers.py | 585 +++---------------------- 3 files changed, 78 insertions(+), 686 deletions(-) diff --git a/pandas/tests/io/excel/test_openpyxl.py b/pandas/tests/io/excel/test_openpyxl.py index 923bcdbf9c091..e0d4a0c12ecdf 100644 --- a/pandas/tests/io/excel/test_openpyxl.py +++ b/pandas/tests/io/excel/test_openpyxl.py @@ -4,11 +4,6 @@ import numpy as np import pytest -from pandas.compat._optional import ( - VERSIONS, - import_optional_dependency, -) - import pandas as pd from pandas import DataFrame import pandas._testing as tm @@ -23,21 +18,6 @@ pytestmark = pytest.mark.parametrize("ext", [".xlsx"]) -def has_min_lxml_and_openpyxl(): - openpyxl = import_optional_dependency("openpyxl", errors="ignore") - lxml = import_optional_dependency("lxml.etree", errors="ignore") - return ( - openpyxl is not None - and openpyxl.__version__ == VERSIONS["openpyxl"] - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"] - ) - - -def openpyxl_installed_and_xlsx_xlsm(path): - return ("xlsm" in path or "xlsx" in path) and has_min_lxml_and_openpyxl() - - def test_to_excel_styleconverter(ext): from openpyxl import styles @@ -71,16 +51,9 @@ def test_to_excel_styleconverter(ext): assert kw["protection"] == protection -def test_write_cells_merge_styled(request, ext): +def test_write_cells_merge_styled(ext): from pandas.io.formats.excel import ExcelCell - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext), - reason="Fails on the min version build", - raises=TypeError, - ) - ) sheet_name = "merge_styled" sty_b1 = {"font": {"color": "00FF0000"}} @@ -113,15 +86,8 @@ def test_write_cells_merge_styled(request, ext): @pytest.mark.parametrize("iso_dates", [True, False]) -def test_kwargs(request, ext, iso_dates): +def test_kwargs(ext, iso_dates): # GH 42286 GH 43445 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext), - reason="Fails on the min version build", - raises=TypeError, - ) - ) kwargs = {"iso_dates": iso_dates} with tm.ensure_clean(ext) as f: msg = re.escape("Use of **kwargs is deprecated") @@ -133,15 +99,8 @@ def test_kwargs(request, ext, iso_dates): @pytest.mark.parametrize("iso_dates", [True, False]) -def test_engine_kwargs_write(request, ext, iso_dates): +def test_engine_kwargs_write(ext, iso_dates): # GH 42286 GH 43445 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext), - reason="Fails on the min version build", - raises=TypeError, - ) - ) engine_kwargs = {"iso_dates": iso_dates} with tm.ensure_clean(ext) as f: with ExcelWriter(f, engine="openpyxl", engine_kwargs=engine_kwargs) as writer: @@ -169,17 +128,10 @@ def test_engine_kwargs_append_invalid(ext): @pytest.mark.parametrize("data_only, expected", [(True, 0), (False, "=1+1")]) -def test_engine_kwargs_append_data_only(request, ext, data_only, expected): +def test_engine_kwargs_append_data_only(ext, data_only, expected): # GH 43445 # tests whether the data_only engine_kwarg actually works well for # openpyxl's load_workbook - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext), - reason="Fails on the min version build", - raises=TypeError, - ) - ) with tm.ensure_clean(ext) as f: DataFrame(["=1+1"]).to_excel(f) with ExcelWriter( @@ -193,14 +145,7 @@ def test_engine_kwargs_append_data_only(request, ext, data_only, expected): @pytest.mark.parametrize( "mode,expected", [("w", ["baz"]), ("a", ["foo", "bar", "baz"])] ) -def test_write_append_mode(request, ext, mode, expected): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext), - reason="Fails on the min version build", - raises=TypeError, - ) - ) +def test_write_append_mode(ext, mode, expected): df = DataFrame([1], columns=["baz"]) with tm.ensure_clean(ext) as f: @@ -230,17 +175,8 @@ def test_write_append_mode(request, ext, mode, expected): ("overlay", 1, ["pear", "banana"]), ], ) -def test_if_sheet_exists_append_modes( - request, ext, if_sheet_exists, num_sheets, expected -): +def test_if_sheet_exists_append_modes(ext, if_sheet_exists, num_sheets, expected): # GH 40230 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df1 = DataFrame({"fruit": ["apple", "banana"]}) df2 = DataFrame({"fruit": ["pear"]}) @@ -271,16 +207,7 @@ def test_if_sheet_exists_append_modes( (1, 1, ["hello", "world"], ["goodbye", "poop"]), ], ) -def test_append_overlay_startrow_startcol( - request, ext, startrow, startcol, greeting, goodbye -): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext), - reason="Fails on the min version build", - raises=TypeError, - ) - ) +def test_append_overlay_startrow_startcol(ext, startrow, startcol, greeting, goodbye): df1 = DataFrame({"greeting": ["hello", "world"], "goodbye": ["goodbye", "people"]}) df2 = DataFrame(["poop"]) @@ -322,15 +249,8 @@ def test_append_overlay_startrow_startcol( ), ], ) -def test_if_sheet_exists_raises(request, ext, if_sheet_exists, msg): +def test_if_sheet_exists_raises(ext, if_sheet_exists, msg): # GH 40230 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame({"fruit": ["pear"]}) with tm.ensure_clean(ext) as f: with pytest.raises(ValueError, match=re.escape(msg)): @@ -341,15 +261,8 @@ def test_if_sheet_exists_raises(request, ext, if_sheet_exists, msg): df.to_excel(writer, sheet_name="foo") -def test_to_excel_with_openpyxl_engine(request, ext): +def test_to_excel_with_openpyxl_engine(ext): # GH 29854 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext), - reason="Fails on the min version build", - raises=TypeError, - ) - ) with tm.ensure_clean(ext) as filename: df1 = DataFrame({"A": np.linspace(1, 10, 10)}) @@ -407,15 +320,8 @@ def test_read_with_bad_dimension( tm.assert_frame_equal(result, expected) -def test_append_mode_file(request, ext): +def test_append_mode_file(ext): # GH 39576 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame() with tm.ensure_clean(ext) as f: diff --git a/pandas/tests/io/excel/test_style.py b/pandas/tests/io/excel/test_style.py index a01ee2fcd1fdf..8a142aebd719d 100644 --- a/pandas/tests/io/excel/test_style.py +++ b/pandas/tests/io/excel/test_style.py @@ -1,11 +1,6 @@ import numpy as np import pytest -from pandas.compat._optional import ( - VERSIONS, - import_optional_dependency, -) - from pandas import DataFrame import pandas._testing as tm @@ -32,21 +27,9 @@ def assert_equal_cell_styles(cell1, cell2): "engine", ["xlsxwriter", "openpyxl"], ) -def test_styler_to_excel_unstyled(request, engine): +def test_styler_to_excel_unstyled(engine): # compare DataFrame.to_excel and Styler.to_excel when no styles applied - mod = pytest.importorskip(engine) - lxml = import_optional_dependency("lxml.etree", errors="ignore") - request.node.add_marker( - pytest.mark.xfail( - engine == "openpyxl", - mod.__version__ == VERSIONS["openpyxl"] - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], - reason="Fails on the min version build", - raises=TypeError, - strict=False, # But passes on other builds - ) - ) + pytest.importorskip(engine) df = DataFrame(np.random.randn(2, 2)) with tm.ensure_clean(".xlsx") as path: with ExcelWriter(path, engine=engine) as writer: @@ -93,20 +76,8 @@ def test_styler_to_excel_unstyled(request, engine): ["xlsxwriter", "openpyxl"], ) @pytest.mark.parametrize("css, attrs, expected", shared_style_params) -def test_styler_to_excel_basic(request, engine, css, attrs, expected): - mod = pytest.importorskip(engine) - lxml = import_optional_dependency("lxml.etree", errors="ignore") - request.node.add_marker( - pytest.mark.xfail( - engine == "openpyxl", - mod.__version__ == VERSIONS["openpyxl"] - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], - reason="Fails on the min version build", - raises=TypeError, - strict=False, # But passes on other builds - ) - ) +def test_styler_to_excel_basic(engine, css, attrs, expected): + pytest.importorskip(engine) df = DataFrame(np.random.randn(1, 1)) styler = df.style.applymap(lambda x: css) @@ -137,20 +108,8 @@ def test_styler_to_excel_basic(request, engine, css, attrs, expected): ["xlsxwriter", "openpyxl"], ) @pytest.mark.parametrize("css, attrs, expected", shared_style_params) -def test_styler_to_excel_basic_indexes(request, engine, css, attrs, expected): - mod = pytest.importorskip(engine) - lxml = import_optional_dependency("lxml.etree", errors="ignore") - request.node.add_marker( - pytest.mark.xfail( - engine == "openpyxl", - mod.__version__ == VERSIONS["openpyxl"] - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], - reason="Fails on the min version build", - raises=TypeError, - strict=False, # But passes on other builds - ) - ) +def test_styler_to_excel_basic_indexes(engine, css, attrs, expected): + pytest.importorskip(engine) df = DataFrame(np.random.randn(1, 1)) styler = df.style @@ -190,18 +149,8 @@ def test_styler_to_excel_basic_indexes(request, engine, css, attrs, expected): assert sc_cell == expected -def test_styler_custom_converter(request): +def test_styler_custom_converter(): openpyxl = pytest.importorskip("openpyxl") - lxml = import_optional_dependency("lxml.etree", errors="ignore") - request.node.add_marker( - pytest.mark.xfail( - openpyxl.__version__ == VERSIONS["openpyxl"] - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"], - reason="Fails on the min version build", - raises=TypeError, - ) - ) def custom_converter(css): return {"font": {"color": {"rgb": "111222"}}} diff --git a/pandas/tests/io/excel/test_writers.py b/pandas/tests/io/excel/test_writers.py index 0053597a74af8..0315783569c23 100644 --- a/pandas/tests/io/excel/test_writers.py +++ b/pandas/tests/io/excel/test_writers.py @@ -11,10 +11,6 @@ import numpy as np import pytest -from pandas.compat._optional import ( - VERSIONS, - import_optional_dependency, -) import pandas.util._test_decorators as td import pandas as pd @@ -37,25 +33,6 @@ ) -def has_min_lxml_and_openpyxl(): - openpyxl = import_optional_dependency("openpyxl", errors="ignore") - lxml = import_optional_dependency("lxml.etree", errors="ignore") - return ( - openpyxl is not None - and openpyxl.__version__ == VERSIONS["openpyxl"] - and lxml is not None - and lxml.__version__ == VERSIONS["lxml.etree"] - ) - - -def openpyxl_installed_and_xlsx_xlsm(path): - return ("xlsm" in path or "xlsx" in path) and has_min_lxml_and_openpyxl() - - -def xlswriter_and_xlsx(path, engine): - return "xlsx" in path and engine == "xlsxwriter" - - @pytest.fixture def path(ext): """ @@ -99,15 +76,8 @@ class TestRoundTrip: "header,expected", [(None, DataFrame([np.nan] * 4)), (0, DataFrame({"Unnamed: 0": [np.nan] * 3}))], ) - def test_read_one_empty_col_no_header(self, request, ext, header, expected): + def test_read_one_empty_col_no_header(self, ext, header, expected): # xref gh-12292 - request.node.add_marker( - pytest.mark.xfail( - ext == ".xlsm" and has_min_lxml_and_openpyxl(), - reason="Fails on the min version build", - raises=TypeError, - ) - ) filename = "no_header" df = DataFrame([["", 1, 100], ["", 2, 200], ["", 3, 300], ["", 4, 400]]) @@ -123,14 +93,7 @@ def test_read_one_empty_col_no_header(self, request, ext, header, expected): "header,expected", [(None, DataFrame([0] + [np.nan] * 4)), (0, DataFrame([np.nan] * 4))], ) - def test_read_one_empty_col_with_header(self, request, ext, header, expected): - request.node.add_marker( - pytest.mark.xfail( - ext == ".xlsm" and has_min_lxml_and_openpyxl(), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_read_one_empty_col_with_header(self, ext, header, expected): filename = "with_header" df = DataFrame([["", 1, 100], ["", 2, 200], ["", 3, 300], ["", 4, 400]]) @@ -142,16 +105,9 @@ def test_read_one_empty_col_with_header(self, request, ext, header, expected): tm.assert_frame_equal(result, expected) - def test_set_column_names_in_parameter(self, request, ext): + def test_set_column_names_in_parameter(self, ext): # GH 12870 : pass down column names associated with # keyword argument names - request.node.add_marker( - pytest.mark.xfail( - ext == ".xlsm" and has_min_lxml_and_openpyxl(), - reason="Fails on the min version build", - raises=TypeError, - ) - ) refdf = DataFrame([[1, "foo"], [2, "bar"], [3, "baz"]], columns=["a", "b"]) with tm.ensure_clean(ext) as pth: @@ -175,19 +131,11 @@ def test_set_column_names_in_parameter(self, request, ext): tm.assert_frame_equal(xlsdf_no_head, refdf) tm.assert_frame_equal(xlsdf_with_head, refdf) - def test_creating_and_reading_multiple_sheets(self, request, ext): + def test_creating_and_reading_multiple_sheets(self, ext): # see gh-9450 # # Test reading multiple sheets, from a runtime # created Excel file with multiple sheets. - request.node.add_marker( - pytest.mark.xfail( - ext == ".xlsm" and has_min_lxml_and_openpyxl(), - reason="Fails on the min version build", - raises=TypeError, - ) - ) - def tdf(col_sheet_name): d, i = [11, 22, 33], [1, 2, 3] return DataFrame(d, i, columns=[col_sheet_name]) @@ -207,15 +155,8 @@ def tdf(col_sheet_name): for s in sheets: tm.assert_frame_equal(dfs[s], dfs_returned[s]) - def test_read_excel_multiindex_empty_level(self, request, ext): + def test_read_excel_multiindex_empty_level(self, ext): # see gh-12453 - request.node.add_marker( - pytest.mark.xfail( - ext == ".xlsm" and has_min_lxml_and_openpyxl(), - reason="Fails on the min version build", - raises=TypeError, - ) - ) with tm.ensure_clean(ext) as path: df = DataFrame( { @@ -268,13 +209,6 @@ def test_read_excel_multiindex_empty_level(self, request, ext): def test_excel_multindex_roundtrip( self, ext, c_idx_names, r_idx_names, c_idx_levels, r_idx_levels, request ): - request.node.add_marker( - pytest.mark.xfail( - ext == ".xlsm" and has_min_lxml_and_openpyxl(), - reason="Fails on the min version build", - raises=TypeError, - ) - ) # see gh-4679 with tm.ensure_clean(ext) as pth: if (c_idx_levels == 1 and c_idx_names) and not ( @@ -321,15 +255,8 @@ def test_excel_multindex_roundtrip( ) tm.assert_frame_equal(df, act, check_names=check_names) - def test_read_excel_parse_dates(self, request, ext): + def test_read_excel_parse_dates(self, ext): # see gh-11544, gh-12051 - request.node.add_marker( - pytest.mark.xfail( - ext == ".xlsm" and has_min_lxml_and_openpyxl(), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame( {"col": [1, 2, 3], "date_strings": pd.date_range("2012-01-01", periods=3)} ) @@ -351,15 +278,8 @@ def test_read_excel_parse_dates(self, request, ext): ) tm.assert_frame_equal(df, res) - def test_multiindex_interval_datetimes(self, request, ext): + def test_multiindex_interval_datetimes(self, ext): # GH 30986 - request.node.add_marker( - pytest.mark.xfail( - ext == ".xlsm" and has_min_lxml_and_openpyxl(), - reason="Fails on the min version build", - raises=TypeError, - ) - ) midx = MultiIndex.from_arrays( [ range(4), @@ -433,14 +353,7 @@ def test_excel_sheet_size(self, path): with pytest.raises(ValueError, match=msg): col_df.to_excel(path) - def test_excel_sheet_by_name_raise(self, path, engine, request): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) and engine == "openpyxl", - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_excel_sheet_by_name_raise(self, path, engine): gt = DataFrame(np.random.randn(10, 2)) gt.to_excel(path) @@ -453,17 +366,7 @@ def test_excel_sheet_by_name_raise(self, path, engine, request): with pytest.raises(ValueError, match=msg): pd.read_excel(xl, "0") - def test_excel_writer_context_manager(self, request, frame, path): - option_name = f"io.excel.{path.split('.')[-1]}.writer" - curr_engine = get_option(option_name) - xlsxwriter_and_xlsx = curr_engine == "xlsxwriter" and "xlsx" in path - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) and not xlsxwriter_and_xlsx, - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_excel_writer_context_manager(self, frame, path): with ExcelWriter(path) as writer: frame.to_excel(writer, "Data1") frame2 = frame.copy() @@ -477,15 +380,7 @@ def test_excel_writer_context_manager(self, request, frame, path): tm.assert_frame_equal(found_df, frame) tm.assert_frame_equal(found_df2, frame2) - def test_roundtrip(self, request, frame, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_roundtrip(self, frame, path): frame = frame.copy() frame["A"][:5] = np.nan @@ -534,15 +429,7 @@ def test_roundtrip(self, request, frame, path): recons = pd.read_excel(path, index_col=0) tm.assert_frame_equal(s.to_frame(), recons) - def test_mixed(self, request, frame, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_mixed(self, frame, path): mixed_frame = frame.copy() mixed_frame["foo"] = "bar" @@ -551,15 +438,7 @@ def test_mixed(self, request, frame, path): recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(mixed_frame, recons) - def test_ts_frame(self, request, tsframe, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_ts_frame(self, tsframe, path): df = tsframe # freq doesn't round-trip @@ -571,15 +450,7 @@ def test_ts_frame(self, request, tsframe, path): recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(df, recons) - def test_basics_with_nan(self, request, frame, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_basics_with_nan(self, frame, path): frame = frame.copy() frame["A"][:5] = np.nan frame.to_excel(path, "test1") @@ -588,15 +459,7 @@ def test_basics_with_nan(self, request, frame, path): frame.to_excel(path, "test1", index=False) @pytest.mark.parametrize("np_type", [np.int8, np.int16, np.int32, np.int64]) - def test_int_types(self, request, np_type, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_int_types(self, np_type, path): # Test np.int values read come back as int # (rather than float which is Excel's format). df = DataFrame(np.random.randint(-10, 10, size=(10, 2)), dtype=np_type) @@ -624,15 +487,7 @@ def test_int_types(self, request, np_type, path): tm.assert_frame_equal(recons, float_frame) @pytest.mark.parametrize("np_type", [np.float16, np.float32, np.float64]) - def test_float_types(self, request, np_type, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_float_types(self, np_type, path): # Test np.float values read come back as float. df = DataFrame(np.random.random_sample(10), dtype=np_type) df.to_excel(path, "test1") @@ -645,15 +500,7 @@ def test_float_types(self, request, np_type, path): tm.assert_frame_equal(df, recons) @pytest.mark.parametrize("np_type", [np.bool8, np.bool_]) - def test_bool_types(self, request, np_type, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_bool_types(self, np_type, path): # Test np.bool8 and np.bool_ values read come back as float. df = DataFrame([1, 0, True, False], dtype=np_type) df.to_excel(path, "test1") @@ -665,15 +512,7 @@ def test_bool_types(self, request, np_type, path): tm.assert_frame_equal(df, recons) - def test_inf_roundtrip(self, request, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_inf_roundtrip(self, path): df = DataFrame([(1, np.inf), (2, 3), (5, -np.inf)]) df.to_excel(path, "test1") @@ -682,15 +521,8 @@ def test_inf_roundtrip(self, request, path): tm.assert_frame_equal(df, recons) - def test_sheets(self, request, frame, tsframe, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_sheets(self, frame, tsframe, path): + # freq doesn't round-trip index = pd.DatetimeIndex(np.asarray(tsframe.index), freq=None) tsframe.index = index @@ -716,15 +548,7 @@ def test_sheets(self, request, frame, tsframe, path): assert "test1" == reader.sheet_names[0] assert "test2" == reader.sheet_names[1] - def test_colaliases(self, request, frame, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_colaliases(self, frame, path): frame = frame.copy() frame["A"][:5] = np.nan @@ -742,15 +566,7 @@ def test_colaliases(self, request, frame, path): xp.columns = col_aliases tm.assert_frame_equal(xp, rs) - def test_roundtrip_indexlabels(self, request, merge_cells, frame, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_roundtrip_indexlabels(self, merge_cells, frame, path): frame = frame.copy() frame["A"][:5] = np.nan @@ -807,15 +623,7 @@ def test_roundtrip_indexlabels(self, request, merge_cells, frame, path): recons = pd.read_excel(reader, sheet_name="test1", index_col=[0, 1]) tm.assert_frame_equal(df, recons) - def test_excel_roundtrip_indexname(self, request, merge_cells, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_excel_roundtrip_indexname(self, merge_cells, path): df = DataFrame(np.random.randn(10, 4)) df.index.name = "foo" @@ -827,18 +635,10 @@ def test_excel_roundtrip_indexname(self, request, merge_cells, path): tm.assert_frame_equal(result, df) assert result.index.name == "foo" - def test_excel_roundtrip_datetime(self, request, merge_cells, tsframe, path): + def test_excel_roundtrip_datetime(self, merge_cells, tsframe, path): # datetime.date, not sure what to test here exactly # freq does not round-trip - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) index = pd.DatetimeIndex(np.asarray(tsframe.index), freq=None) tsframe.index = index @@ -852,18 +652,10 @@ def test_excel_roundtrip_datetime(self, request, merge_cells, tsframe, path): tm.assert_frame_equal(tsframe, recons) - def test_excel_date_datetime_format(self, request, engine, ext, path): + def test_excel_date_datetime_format(self, engine, ext, path): # see gh-4133 # # Excel output format strings - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame( [ [date(2014, 1, 31), date(1999, 9, 24)], @@ -904,18 +696,10 @@ def test_excel_date_datetime_format(self, request, engine, 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, request, path): + def test_to_excel_interval_no_labels(self, path): # see gh-19242 # # Test writing Interval without labels. - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame(np.random.randint(-10, 10, size=(20, 1)), dtype=np.int64) expected = df.copy() @@ -927,18 +711,10 @@ def test_to_excel_interval_no_labels(self, request, path): recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(expected, recons) - def test_to_excel_interval_labels(self, request, path): + def test_to_excel_interval_labels(self, path): # see gh-19242 # # Test writing Interval with labels. - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame(np.random.randint(-10, 10, size=(20, 1)), dtype=np.int64) expected = df.copy() intervals = pd.cut( @@ -952,18 +728,10 @@ def test_to_excel_interval_labels(self, request, path): recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(expected, recons) - def test_to_excel_timedelta(self, request, path): + def test_to_excel_timedelta(self, path): # see gh-19242, gh-9155 # # Test writing timedelta to xls. - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame( np.random.randint(-10, 10, size=(20, 1)), columns=["A"], dtype=np.int64 ) @@ -979,15 +747,7 @@ def test_to_excel_timedelta(self, request, path): recons = pd.read_excel(reader, sheet_name="test1", index_col=0) tm.assert_frame_equal(expected, recons) - def test_to_excel_periodindex(self, request, tsframe, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_to_excel_periodindex(self, tsframe, path): xp = tsframe.resample("M", kind="period").mean() xp.to_excel(path, "sht1") @@ -996,15 +756,7 @@ def test_to_excel_periodindex(self, request, tsframe, path): 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, request, merge_cells, frame, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_to_excel_multiindex(self, merge_cells, frame, path): arrays = np.arange(len(frame.index) * 2).reshape(2, -1) new_index = MultiIndex.from_arrays(arrays, names=["first", "second"]) frame.index = new_index @@ -1019,15 +771,7 @@ def test_to_excel_multiindex(self, request, merge_cells, frame, path): tm.assert_frame_equal(frame, df) # GH13511 - def test_to_excel_multiindex_nan_label(self, request, merge_cells, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_to_excel_multiindex_nan_label(self, merge_cells, path): df = DataFrame({"A": [None, 2, 3], "B": [10, 20, 30], "C": np.random.sample(3)}) df = df.set_index(["A", "B"]) @@ -1038,15 +782,7 @@ def test_to_excel_multiindex_nan_label(self, request, merge_cells, path): # 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, request, merge_cells, frame, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_to_excel_multiindex_cols(self, merge_cells, frame, path): arrays = np.arange(len(frame.index) * 2).reshape(2, -1) new_index = MultiIndex.from_arrays(arrays, names=["first", "second"]) frame.index = new_index @@ -1068,16 +804,8 @@ def test_to_excel_multiindex_cols(self, request, 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, request, merge_cells, tsframe, path): + def test_to_excel_multiindex_dates(self, merge_cells, tsframe, path): # try multiindex with dates - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) new_index = [tsframe.index, np.arange(len(tsframe.index))] tsframe.index = MultiIndex.from_arrays(new_index) @@ -1089,16 +817,8 @@ def test_to_excel_multiindex_dates(self, request, merge_cells, tsframe, path): tm.assert_frame_equal(tsframe, recons) assert recons.index.names == ("time", "foo") - def test_to_excel_multiindex_no_write_index(self, request, path): + def test_to_excel_multiindex_no_write_index(self, path): # Test writing and re-reading a MI without the index. GH 5616. - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) # Initial non-MI frame. frame1 = DataFrame({"a": [10, 20], "b": [30, 40], "c": [50, 60]}) @@ -1118,15 +838,7 @@ def test_to_excel_multiindex_no_write_index(self, request, path): # Test that it is the same as the initial frame. tm.assert_frame_equal(frame1, frame3) - def test_to_excel_float_format(self, request, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_to_excel_float_format(self, path): df = DataFrame( [[0.123456, 0.234567, 0.567567], [12.32112, 123123.2, 321321.2]], index=["A", "B"], @@ -1144,7 +856,7 @@ def test_to_excel_float_format(self, request, path): ) tm.assert_frame_equal(result, expected) - def test_to_excel_output_encoding(self, request, ext): + def test_to_excel_output_encoding(self, ext): # Avoid mixed inferred_type. df = DataFrame( [["\u0192", "\u0193", "\u0194"], ["\u0195", "\u0196", "\u0197"]], @@ -1153,29 +865,11 @@ def test_to_excel_output_encoding(self, request, ext): ) with tm.ensure_clean("__tmp_to_excel_float_format__." + ext) as filename: - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(filename) - and not xlswriter_and_xlsx( - filename, request.getfixturevalue("engine") - ), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df.to_excel(filename, sheet_name="TestSheet", encoding="utf8") result = pd.read_excel(filename, sheet_name="TestSheet", index_col=0) tm.assert_frame_equal(result, df) - def test_to_excel_unicode_filename(self, request, ext, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_to_excel_unicode_filename(self, ext, path): with tm.ensure_clean("\u0192u." + ext) as filename: try: f = open(filename, "wb") @@ -1205,17 +899,8 @@ def test_to_excel_unicode_filename(self, request, ext, path): @pytest.mark.parametrize("r_idx_nlevels", [1, 2, 3]) @pytest.mark.parametrize("c_idx_nlevels", [1, 2, 3]) def test_excel_010_hemstring( - self, request, merge_cells, c_idx_nlevels, r_idx_nlevels, use_headers, path + self, merge_cells, c_idx_nlevels, r_idx_nlevels, use_headers, path ): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) - def roundtrip(data, header=True, parser_hdr=0, index=True): data.to_excel(path, header=header, merge_cells=merge_cells, index=index) @@ -1265,16 +950,8 @@ 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, request, path): + def test_duplicated_columns(self, path): # see gh-5235 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame([[1, 2, 3], [1, 2, 3], [1, 2, 3]], columns=["A", "B", "B"]) df.to_excel(path, "test1") expected = DataFrame( @@ -1312,16 +989,8 @@ def test_duplicated_columns(self, request, path): with pytest.raises(ValueError, match=msg): pd.read_excel(path, sheet_name="test1", header=None, mangle_dupe_cols=False) - def test_swapped_columns(self, request, path): + def test_swapped_columns(self, path): # Test for issue #5427. - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) write_frame = DataFrame({"A": [1, 1, 1], "B": [2, 2, 2]}) write_frame.to_excel(path, "test1", columns=["B", "A"]) @@ -1349,18 +1018,8 @@ def test_invalid_columns(self, path): (False, None), # Dont include index in write to file ], ) - def test_write_subset_columns( - self, request, path, to_excel_index, read_excel_index_col - ): + def test_write_subset_columns(self, path, to_excel_index, read_excel_index_col): # GH 31677 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) write_frame = DataFrame({"A": [1, 1, 1], "B": [2, 2, 2], "C": [3, 3, 3]}) write_frame.to_excel( path, "col_subset_bug", columns=["A", "B"], index=to_excel_index @@ -1373,18 +1032,11 @@ def test_write_subset_columns( tm.assert_frame_equal(expected, read_frame) - def test_comment_arg(self, request, path): + def test_comment_arg(self, path): # see gh-18735 # # Test the comment argument functionality to pd.read_excel. - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + # Create file to read in. df = DataFrame({"A": ["one", "#one", "one"], "B": ["two", "two", "#two"]}) df.to_excel(path, "test_c") @@ -1399,17 +1051,10 @@ def test_comment_arg(self, request, path): result2 = pd.read_excel(path, sheet_name="test_c", comment="#", index_col=0) tm.assert_frame_equal(result1, result2) - def test_comment_default(self, request, path): + def test_comment_default(self, path): # Re issue #18735 # Test the comment argument default to pd.read_excel - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + # Create file to read in df = DataFrame({"A": ["one", "#one", "one"], "B": ["two", "two", "#two"]}) df.to_excel(path, "test_c") @@ -1419,18 +1064,11 @@ def test_comment_default(self, request, path): result2 = pd.read_excel(path, sheet_name="test_c", comment=None) tm.assert_frame_equal(result1, result2) - def test_comment_used(self, request, path): + def test_comment_used(self, path): # see gh-18735 # # Test the comment argument is working as expected when used. - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + # Create file to read in. df = DataFrame({"A": ["one", "#one", "one"], "B": ["two", "two", "#two"]}) df.to_excel(path, "test_c") @@ -1440,17 +1078,10 @@ def test_comment_used(self, request, path): result = pd.read_excel(path, sheet_name="test_c", comment="#", index_col=0) tm.assert_frame_equal(result, expected) - def test_comment_empty_line(self, request, path): + def test_comment_empty_line(self, path): # Re issue #18735 # Test that pd.read_excel ignores commented lines at the end of file - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + df = DataFrame({"a": ["1", "#2"], "b": ["2", "3"]}) df.to_excel(path, index=False) @@ -1459,14 +1090,8 @@ def test_comment_empty_line(self, request, path): result = pd.read_excel(path, comment="#") tm.assert_frame_equal(result, expected) - def test_datetimes(self, request, path): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_datetimes(self, path): + # Test writing and reading datetimes. For issue #9139. (xref #9185) datetimes = [ datetime(2013, 1, 13, 1, 2, 3), @@ -1493,17 +1118,8 @@ def test_datetimes(self, request, path): tm.assert_series_equal(write_frame["A"], read_frame["A"]) - def test_bytes_io(self, request, engine): + def test_bytes_io(self, engine): # see gh-7074 - ext = request.getfixturevalue("ext") - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext) - and not xlswriter_and_xlsx(ext, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) with BytesIO() as bio: df = DataFrame(np.random.randn(10, 2)) @@ -1515,16 +1131,8 @@ def test_bytes_io(self, request, engine): reread_df = pd.read_excel(bio, index_col=0) tm.assert_frame_equal(df, reread_df) - def test_write_lists_dict(self, request, path): + def test_write_lists_dict(self, path): # see gh-8188. - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame( { "mixed": ["a", ["b", "c"], {"d": "e", "f": 2}], @@ -1541,32 +1149,16 @@ def test_write_lists_dict(self, request, path): tm.assert_frame_equal(read, expected) - def test_render_as_column_name(self, request, path): + def test_render_as_column_name(self, path): # see gh-34331 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame({"render": [1, 2], "data": [3, 4]}) df.to_excel(path, "Sheet1") read = pd.read_excel(path, "Sheet1", index_col=0) expected = df tm.assert_frame_equal(read, expected) - def test_true_and_false_value_options(self, request, path): + def test_true_and_false_value_options(self, path): # see gh-13347 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame([["foo", "bar"]], columns=["col1", "col2"]) expected = df.replace({"foo": True, "bar": False}) @@ -1576,31 +1168,15 @@ def test_true_and_false_value_options(self, request, path): ) tm.assert_frame_equal(read_frame, expected) - def test_freeze_panes(self, request, path): + def test_freeze_panes(self, path): # see gh-15160 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) expected = DataFrame([[1, 2], [3, 4]], columns=["col1", "col2"]) expected.to_excel(path, "Sheet1", freeze_panes=(1, 1)) result = pd.read_excel(path, index_col=0) tm.assert_frame_equal(result, expected) - def test_path_path_lib(self, request, engine, ext): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext) - and not xlswriter_and_xlsx(ext, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_path_path_lib(self, engine, ext): df = tm.makeDataFrame() writer = partial(df.to_excel, engine=engine) @@ -1608,15 +1184,7 @@ def test_path_path_lib(self, request, engine, ext): result = tm.round_trip_pathlib(writer, reader, path=f"foo{ext}") tm.assert_frame_equal(result, df) - def test_path_local_path(self, request, engine, ext): - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(ext) - and not xlswriter_and_xlsx(ext, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) + def test_path_local_path(self, engine, ext): df = tm.makeDataFrame() writer = partial(df.to_excel, engine=engine) @@ -1624,16 +1192,8 @@ def test_path_local_path(self, request, engine, ext): result = tm.round_trip_localpath(writer, reader, path=f"foo{ext}") tm.assert_frame_equal(result, df) - def test_merged_cell_custom_objects(self, request, merge_cells, path): + def test_merged_cell_custom_objects(self, merge_cells, path): # see GH-27006 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) mi = MultiIndex.from_tuples( [ (pd.Period("2018"), pd.Period("2018Q1")), @@ -1642,15 +1202,8 @@ def test_merged_cell_custom_objects(self, request, merge_cells, path): ) expected = DataFrame(np.ones((2, 2)), columns=mi) expected.to_excel(path) - option_name = f"io.excel.{path.split('.')[-1]}.writer" - curr_engine = get_option(option_name) - xlsxwriter_and_xlsx_produces_resourcewarnings = ( - curr_engine == "xlsxwriter" and "xlsx" in path - ) with tm.assert_produces_warning( - FutureWarning, - match="convert_float is deprecated", - raise_on_extra_warnings=not xlsxwriter_and_xlsx_produces_resourcewarnings, + FutureWarning, match="convert_float is deprecated" ): result = pd.read_excel( path, header=[0, 1], index_col=0, convert_float=False @@ -1664,16 +1217,8 @@ def test_merged_cell_custom_objects(self, request, merge_cells, path): tm.assert_frame_equal(expected, result) @pytest.mark.parametrize("dtype", [None, object]) - def test_raise_when_saving_timezones(self, request, dtype, tz_aware_fixture, path): + def test_raise_when_saving_timezones(self, dtype, tz_aware_fixture, path): # GH 27008, GH 7056 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) tz = tz_aware_fixture data = pd.Timestamp("2019", tz=tz) df = DataFrame([data], dtype=dtype) @@ -1685,16 +1230,8 @@ def test_raise_when_saving_timezones(self, request, dtype, tz_aware_fixture, pat with pytest.raises(ValueError, match="Excel does not support"): df.to_excel(path) - def test_excel_duplicate_columns_with_names(self, request, path): + def test_excel_duplicate_columns_with_names(self, path): # GH#39695 - request.node.add_marker( - pytest.mark.xfail( - openpyxl_installed_and_xlsx_xlsm(path) - and not xlswriter_and_xlsx(path, request.getfixturevalue("engine")), - reason="Fails on the min version build", - raises=TypeError, - ) - ) df = DataFrame({"A": [0, 1], "B": [10, 11]}) df.to_excel(path, columns=["A", "B", "A"], index=False) From 0bc5d8c850db7f28783a85e77c5fc71b89ef1497 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Fri, 31 Dec 2021 20:05:13 -0800 Subject: [PATCH 13/15] Add more downstream dependencies that are untested --- ci/deps/actions-38-downstream_compat.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci/deps/actions-38-downstream_compat.yaml b/ci/deps/actions-38-downstream_compat.yaml index d23a0e93b3a64..eb63f2cb2b06e 100644 --- a/ci/deps/actions-38-downstream_compat.yaml +++ b/ci/deps/actions-38-downstream_compat.yaml @@ -53,7 +53,9 @@ dependencies: - dask - ipython - geopandas + - pg8000 - python-snappy + - seaborn - scikit-learn - statsmodels - brotlipy @@ -61,4 +63,5 @@ dependencies: - pandas-datareader - pyyaml - pip: + - py - torch From a2c73231a4a20a39c1c01a715e3cbc6b30130581 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Fri, 31 Dec 2021 20:11:58 -0800 Subject: [PATCH 14/15] Undo pg8000 --- ci/deps/actions-38-downstream_compat.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/ci/deps/actions-38-downstream_compat.yaml b/ci/deps/actions-38-downstream_compat.yaml index eb63f2cb2b06e..65ba0f633b9b4 100644 --- a/ci/deps/actions-38-downstream_compat.yaml +++ b/ci/deps/actions-38-downstream_compat.yaml @@ -53,7 +53,6 @@ dependencies: - dask - ipython - geopandas - - pg8000 - python-snappy - seaborn - scikit-learn From 2d2ce98420529c38c41c5988083fa29f0ebf8b88 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke Date: Tue, 4 Jan 2022 10:40:31 -0800 Subject: [PATCH 15/15] Install py from conda --- ci/deps/actions-38-downstream_compat.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/deps/actions-38-downstream_compat.yaml b/ci/deps/actions-38-downstream_compat.yaml index 65ba0f633b9b4..af4f7dee851d5 100644 --- a/ci/deps/actions-38-downstream_compat.yaml +++ b/ci/deps/actions-38-downstream_compat.yaml @@ -61,6 +61,6 @@ dependencies: - coverage - pandas-datareader - pyyaml + - py - pip: - - py - torch