Skip to content

Commit 98cb9a5

Browse files
authored
REGR: ExcelWriter.book not settable (#48943)
1 parent d8e7651 commit 98cb9a5

File tree

7 files changed

+79
-4
lines changed

7 files changed

+79
-4
lines changed

doc/source/whatsnew/v1.5.1.rst

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ Fixed regressions
8484
- Fixed Regression in :meth:`DataFrameGroupBy.apply` when user defined function is called on an empty dataframe (:issue:`47985`)
8585
- Fixed regression in :meth:`DataFrame.apply` when passing non-zero ``axis`` via keyword argument (:issue:`48656`)
8686
- Fixed regression in :meth:`Series.groupby` and :meth:`DataFrame.groupby` when the grouper is a nullable data type (e.g. :class:`Int64`) or a PyArrow-backed string array, contains null values, and ``dropna=False`` (:issue:`48794`)
87+
- Fixed regression in :class:`ExcelWriter` where the ``book`` attribute could no longer be set; however setting this attribute is now deprecated and this ability will be removed in a future version of pandas (:issue:`48780`)
8788

8889
.. ---------------------------------------------------------------------------
8990

pandas/io/excel/_base.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,14 @@ def book(self):
12031203
"""
12041204
pass
12051205

1206+
@book.setter
1207+
@abc.abstractmethod
1208+
def book(self, other) -> None:
1209+
"""
1210+
Set book instance. Class type will depend on the engine used.
1211+
"""
1212+
pass
1213+
12061214
def write_cells(
12071215
self,
12081216
cells,
@@ -1332,12 +1340,24 @@ def _deprecate(self, attr: str) -> None:
13321340
Deprecate attribute or method for ExcelWriter.
13331341
"""
13341342
warnings.warn(
1335-
f"{attr} is not part of the public API, usage can give in unexpected "
1343+
f"{attr} is not part of the public API, usage can give unexpected "
13361344
"results and will be removed in a future version",
13371345
FutureWarning,
13381346
stacklevel=find_stack_level(inspect.currentframe()),
13391347
)
13401348

1349+
def _deprecate_set_book(self) -> None:
1350+
"""
1351+
Deprecate setting the book attribute - GH#48780.
1352+
"""
1353+
warnings.warn(
1354+
"Setting the `book` attribute is not part of the public API, "
1355+
"usage can give unexpected or corrupted results and will be "
1356+
"removed in a future version",
1357+
FutureWarning,
1358+
stacklevel=find_stack_level(inspect.currentframe()),
1359+
)
1360+
13411361
@property
13421362
def date_format(self) -> str:
13431363
"""

pandas/io/excel/_odswriter.py

+10
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
)
2525

2626
if TYPE_CHECKING:
27+
from odf.opendocument import OpenDocumentSpreadsheet
28+
2729
from pandas.io.formats.excel import ExcelCell
2830

2931

@@ -70,6 +72,14 @@ def book(self):
7072
"""
7173
return self._book
7274

75+
@book.setter
76+
def book(self, other: OpenDocumentSpreadsheet) -> None:
77+
"""
78+
Set book instance. Class type will depend on the engine used.
79+
"""
80+
self._deprecate_set_book()
81+
self._book = other
82+
7383
@property
7484
def sheets(self) -> dict[str, Any]:
7585
"""Mapping of sheet names to sheet objects."""

pandas/io/excel/_openpyxl.py

+8
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ def book(self) -> Workbook:
8888
"""
8989
return self._book
9090

91+
@book.setter
92+
def book(self, other: Workbook) -> None:
93+
"""
94+
Set book instance. Class type will depend on the engine used.
95+
"""
96+
self._deprecate_set_book()
97+
self._book = other
98+
9199
@property
92100
def sheets(self) -> dict[str, Any]:
93101
"""Mapping of sheet names to sheet objects."""

pandas/io/excel/_xlsxwriter.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
from __future__ import annotations
22

3-
from typing import Any
3+
from typing import (
4+
TYPE_CHECKING,
5+
Any,
6+
)
47

58
import pandas._libs.json as json
69
from pandas._typing import (
@@ -15,6 +18,9 @@
1518
validate_freeze_panes,
1619
)
1720

21+
if TYPE_CHECKING:
22+
from xlsxwriter import Workbook
23+
1824

1925
class _XlsxStyler:
2026
# Map from openpyxl-oriented styles to flatter xlsxwriter representation
@@ -218,6 +224,14 @@ def book(self):
218224
"""
219225
return self._book
220226

227+
@book.setter
228+
def book(self, other: Workbook) -> None:
229+
"""
230+
Set book instance. Class type will depend on the engine used.
231+
"""
232+
self._deprecate_set_book()
233+
self._book = other
234+
221235
@property
222236
def sheets(self) -> dict[str, Any]:
223237
result = self.book.sheetnames

pandas/io/excel/_xlwt.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
)
2222

2323
if TYPE_CHECKING:
24-
from xlwt import XFStyle
24+
from xlwt import (
25+
Workbook,
26+
XFStyle,
27+
)
2528

2629

2730
class XlwtWriter(ExcelWriter):
@@ -64,14 +67,22 @@ def __init__(
6467
self._fm_date = xlwt.easyxf(num_format_str=self._date_format)
6568

6669
@property
67-
def book(self):
70+
def book(self) -> Workbook:
6871
"""
6972
Book instance of class xlwt.Workbook.
7073
7174
This attribute can be used to access engine-specific features.
7275
"""
7376
return self._book
7477

78+
@book.setter
79+
def book(self, other: Workbook) -> None:
80+
"""
81+
Set book instance. Class type will depend on the engine used.
82+
"""
83+
self._deprecate_set_book()
84+
self._book = other
85+
7586
@property
7687
def sheets(self) -> dict[str, Any]:
7788
"""Mapping of sheet names to sheet objects."""

pandas/tests/io/excel/test_writers.py

+11
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,17 @@ def test_deprecated_method(self, engine, ext, attr, args):
13011301
with tm.assert_produces_warning(FutureWarning, match=msg):
13021302
getattr(writer, attr)(*args)
13031303

1304+
def test_deprecated_book_setter(self, engine, ext):
1305+
# GH#48780
1306+
with tm.ensure_clean(ext) as path:
1307+
with ExcelWriter(path) as writer:
1308+
msg = "Setting the `book` attribute is not part of the public API"
1309+
# Some engines raise if nothing is written
1310+
DataFrame().to_excel(writer)
1311+
book = writer.book
1312+
with tm.assert_produces_warning(FutureWarning, match=msg):
1313+
writer.book = book
1314+
13041315

13051316
class TestExcelWriterEngineTests:
13061317
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)