Skip to content

Commit

Permalink
DEPR: Remove deprecated ExcelWriter methods (#50093)
Browse files Browse the repository at this point in the history
* DEPR: Remove deprecated ExcelWriter methods

* Fixup

* asv fix

* Second asv fix

* fixup

Co-authored-by: Patrick Hoefler <61934744+phofl@users.noreply.github.com>
  • Loading branch information
rhshadrach and phofl committed Dec 13, 2022
1 parent 43bff73 commit 1f836f1
Show file tree
Hide file tree
Showing 7 changed files with 12 additions and 178 deletions.
18 changes: 8 additions & 10 deletions asv_bench/benchmarks/io/excel.py
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
Expand Up @@ -677,6 +677,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
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
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
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
@@ -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
Expand Up @@ -1234,42 +1234,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

0 comments on commit 1f836f1

Please sign in to comment.