Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEPR: Remove deprecated ExcelWriter methods #50093

Merged
merged 9 commits into from
Dec 13, 2022
18 changes: 8 additions & 10 deletions asv_bench/benchmarks/io/excel.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ def setup(self, engine):
def time_write_excel(self, engine):
bio = BytesIO()
bio.seek(0)
writer = ExcelWriter(bio, engine=engine)
self.df.to_excel(writer, sheet_name="Sheet1")
writer.save()
with ExcelWriter(bio, engine=engine) as writer:
self.df.to_excel(writer, sheet_name="Sheet1")


class WriteExcelStyled:
Expand All @@ -57,13 +56,12 @@ def setup(self, engine):
def time_write_excel_style(self, engine):
bio = BytesIO()
bio.seek(0)
writer = ExcelWriter(bio, engine=engine)
df_style = self.df.style
df_style.applymap(lambda x: "border: red 1px solid;")
df_style.applymap(lambda x: "color: blue")
df_style.applymap(lambda x: "border-color: green black", subset=["float1"])
df_style.to_excel(writer, sheet_name="Sheet1")
writer.save()
with ExcelWriter(bio, engine=engine) as writer:
df_style = self.df.style
df_style.applymap(lambda x: "border: red 1px solid;")
df_style.applymap(lambda x: "color: blue")
df_style.applymap(lambda x: "border-color: green black", subset=["float1"])
df_style.to_excel(writer, sheet_name="Sheet1")


class ReadExcel:
Expand Down
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v2.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,8 @@ Removal of prior version deprecations/changes
- Changed default of ``numeric_only`` to ``False`` in :class:`.Resampler` methods (:issue:`47177`)
- Using the method :meth:`DataFrameGroupBy.transform` with a callable that returns DataFrames will align to the input's index (:issue:`47244`)
- When providing a list of columns of length one to :meth:`DataFrame.groupby`, the keys that are returned by iterating over the resulting :class:`DataFrameGroupBy` object will now be tuples of length one (:issue:`47761`)
- Removed deprecated methods :meth:`ExcelWriter.write_cells`, :meth:`ExcelWriter.save`, :meth:`ExcelWriter.cur_sheet`, :meth:`ExcelWriter.handles`, :meth:`ExcelWriter.path` (:issue:`45795`)
- The :class:`ExcelWriter` attribute ``book`` can no longer be set; it is still available to be accessed and mutated (:issue:`48943`)
-

.. ---------------------------------------------------------------------------
Expand Down
100 changes: 1 addition & 99 deletions pandas/io/excel/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
cast,
overload,
)
import warnings
import zipfile

from pandas._config import config
Expand All @@ -44,7 +43,6 @@
Appender,
doc,
)
from pandas.util._exceptions import find_stack_level

from pandas.core.dtypes.common import (
is_bool,
Expand Down Expand Up @@ -1136,40 +1134,6 @@ def book(self):
This attribute can be used to access engine-specific features.
"""

@book.setter
@abc.abstractmethod
def book(self, other) -> None:
"""
Set book instance. Class type will depend on the engine used.
"""

def write_cells(
self,
cells,
sheet_name: str | None = None,
startrow: int = 0,
startcol: int = 0,
freeze_panes: tuple[int, int] | None = None,
) -> None:
"""
Write given formatted cells into Excel an excel sheet

.. deprecated:: 1.5.0

Parameters
----------
cells : generator
cell of formatted data to save to Excel sheet
sheet_name : str, default None
Name of Excel sheet, if None, then use self.cur_sheet
startrow : upper left cell row to dump data frame
startcol : upper left cell column to dump data frame
freeze_panes: int tuple of length 2
contains the bottom-most row and right-most column to freeze
"""
self._deprecate("write_cells")
return self._write_cells(cells, sheet_name, startrow, startcol, freeze_panes)

@abc.abstractmethod
def _write_cells(
self,
Expand All @@ -1194,15 +1158,6 @@ def _write_cells(
contains the bottom-most row and right-most column to freeze
"""

def save(self) -> None:
"""
Save workbook to disk.

.. deprecated:: 1.5.0
"""
self._deprecate("save")
return self._save()

@abc.abstractmethod
def _save(self) -> None:
"""
Expand Down Expand Up @@ -1232,7 +1187,7 @@ def __init__(
# the excel backend first read the existing file and then write any data to it
mode = mode.replace("a", "r+")

# cast ExcelWriter to avoid adding 'if self.handles is not None'
# cast ExcelWriter to avoid adding 'if self._handles is not None'
self._handles = IOHandles(
cast(IO[bytes], path), compression={"compression": None}
)
Expand Down Expand Up @@ -1264,29 +1219,6 @@ def __init__(
if_sheet_exists = "error"
self._if_sheet_exists = if_sheet_exists

def _deprecate(self, attr: str) -> None:
"""
Deprecate attribute or method for ExcelWriter.
"""
warnings.warn(
f"{attr} is not part of the public API, usage can give unexpected "
"results and will be removed in a future version",
FutureWarning,
stacklevel=find_stack_level(),
)

def _deprecate_set_book(self) -> None:
"""
Deprecate setting the book attribute - GH#48780.
"""
warnings.warn(
"Setting the `book` attribute is not part of the public API, "
"usage can give unexpected or corrupted results and will be "
"removed in a future version",
FutureWarning,
stacklevel=find_stack_level(),
)

@property
def date_format(self) -> str:
"""
Expand All @@ -1308,36 +1240,6 @@ def if_sheet_exists(self) -> str:
"""
return self._if_sheet_exists

@property
def cur_sheet(self):
"""
Current sheet for writing.

.. deprecated:: 1.5.0
"""
self._deprecate("cur_sheet")
return self._cur_sheet

@property
def handles(self) -> IOHandles[bytes]:
"""
Handles to Excel sheets.

.. deprecated:: 1.5.0
"""
self._deprecate("handles")
return self._handles

@property
def path(self):
"""
Path to Excel file.

.. deprecated:: 1.5.0
"""
self._deprecate("path")
return self._path

def __fspath__(self) -> str:
return getattr(self._handles.handle, "name", "")

Expand Down
10 changes: 0 additions & 10 deletions pandas/io/excel/_odswriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
)

if TYPE_CHECKING:
from odf.opendocument import OpenDocumentSpreadsheet

from pandas.io.formats.excel import ExcelCell


Expand Down Expand Up @@ -72,14 +70,6 @@ def book(self):
"""
return self._book

@book.setter
def book(self, other: OpenDocumentSpreadsheet) -> None:
"""
Set book instance. Class type will depend on the engine used.
"""
self._deprecate_set_book()
self._book = other

@property
def sheets(self) -> dict[str, Any]:
"""Mapping of sheet names to sheet objects."""
Expand Down
8 changes: 0 additions & 8 deletions pandas/io/excel/_openpyxl.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,6 @@ def book(self) -> Workbook:
"""
return self._book

@book.setter
def book(self, other: Workbook) -> None:
"""
Set book instance. Class type will depend on the engine used.
"""
self._deprecate_set_book()
self._book = other

@property
def sheets(self) -> dict[str, Any]:
"""Mapping of sheet names to sheet objects."""
Expand Down
16 changes: 1 addition & 15 deletions pandas/io/excel/_xlsxwriter.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
from __future__ import annotations

from typing import (
TYPE_CHECKING,
Any,
)
from typing import Any

from pandas._libs import json
from pandas._typing import (
Expand All @@ -18,9 +15,6 @@
validate_freeze_panes,
)

if TYPE_CHECKING:
from xlsxwriter import Workbook


class _XlsxStyler:
# Map from openpyxl-oriented styles to flatter xlsxwriter representation
Expand Down Expand Up @@ -224,14 +218,6 @@ def book(self):
"""
return self._book

@book.setter
def book(self, other: Workbook) -> None:
"""
Set book instance. Class type will depend on the engine used.
"""
self._deprecate_set_book()
self._book = other

@property
def sheets(self) -> dict[str, Any]:
result = self.book.sheetnames
Expand Down
36 changes: 0 additions & 36 deletions pandas/tests/io/excel/test_writers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1233,42 +1233,6 @@ def test_to_excel_empty_frame(self, engine, ext):
expected = DataFrame()
tm.assert_frame_equal(result, expected)

@pytest.mark.parametrize("attr", ["cur_sheet", "handles", "path"])
def test_deprecated_attr(self, engine, ext, attr):
# GH#45572
with tm.ensure_clean(ext) as path:
with ExcelWriter(path) as writer:
msg = f"{attr} is not part of the public API"
with tm.assert_produces_warning(FutureWarning, match=msg):
getattr(writer, attr)
# Some engines raise if nothing is written
DataFrame().to_excel(writer)

@pytest.mark.filterwarnings("ignore:Calling close():UserWarning:xlsxwriter")
@pytest.mark.parametrize(
"attr, args", [("save", ()), ("write_cells", ([], "test"))]
)
def test_deprecated_method(self, engine, ext, attr, args):
# GH#45572
with tm.ensure_clean(ext) as path:
with ExcelWriter(path) as writer:
msg = f"{attr} is not part of the public API"
# Some engines raise if nothing is written
DataFrame().to_excel(writer)
with tm.assert_produces_warning(FutureWarning, match=msg):
getattr(writer, attr)(*args)

def test_deprecated_book_setter(self, engine, ext):
# GH#48780
with tm.ensure_clean(ext) as path:
with ExcelWriter(path) as writer:
msg = "Setting the `book` attribute is not part of the public API"
# Some engines raise if nothing is written
DataFrame().to_excel(writer)
book = writer.book
with tm.assert_produces_warning(FutureWarning, match=msg):
writer.book = book


class TestExcelWriterEngineTests:
@pytest.mark.parametrize(
Expand Down