Skip to content

Commit e8716c7

Browse files
committed
Rename parameter to if_sheet_exists
1 parent 5bce9ac commit e8716c7

File tree

4 files changed

+56
-39
lines changed

4 files changed

+56
-39
lines changed

doc/source/whatsnew/v1.3.0.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ Other enhancements
125125
- :func:`to_numeric` now supports downcasting of nullable ``ExtensionDtype`` objects (:issue:`33013`)
126126
- Add support for dict-like names in :class:`MultiIndex.set_names` and :class:`MultiIndex.rename` (:issue:`20421`)
127127
- :func:`pandas.read_excel` can now auto detect .xlsb files (:issue:`35416`)
128-
- :class:`pandas.ExcelWriter` now accepts an ``if_exists`` parameter to control the behaviour of append mode when writing to existing sheets (:issue:`40230`)
128+
- :class:`pandas.ExcelWriter` now accepts an ``if_sheet_exists`` parameter to control the behaviour of append mode when writing to existing sheets (:issue:`40230`)
129129
- :meth:`.Rolling.sum`, :meth:`.Expanding.sum`, :meth:`.Rolling.mean`, :meth:`.Expanding.mean`, :meth:`.Rolling.median`, :meth:`.Expanding.median`, :meth:`.Rolling.max`, :meth:`.Expanding.max`, :meth:`.Rolling.min`, and :meth:`.Expanding.min` now support ``Numba`` execution with the ``engine`` keyword (:issue:`38895`)
130130
- :meth:`DataFrame.apply` can now accept NumPy unary operators as strings, e.g. ``df.apply("sqrt")``, which was already the case for :meth:`Series.apply` (:issue:`39116`)
131131
- :meth:`DataFrame.apply` can now accept non-callable DataFrame properties as strings, e.g. ``df.apply("size")``, which was already the case for :meth:`Series.apply` (:issue:`39116`)

pandas/io/excel/_base.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -666,14 +666,15 @@ class ExcelWriter(metaclass=abc.ABCMeta):
666666
be parsed by ``fsspec``, e.g., starting "s3://", "gcs://".
667667
668668
.. versionadded:: 1.2.0
669-
if_exists : {'new_sheet', 'overwrite_sheet', 'overwrite_cells'}, default 'new_sheet'
670-
How to behave when trying to write to a sheet that already
671-
exists (append mode only).
669+
if_sheet_exists : {'avoid', 'replace', 'overwrite', 'fail'}, default 'avoid'
670+
How to behave when trying to write to a sheet that already
671+
exists (append mode only).
672672
673-
* new_sheet: Create a new sheet with a different name.
674-
* overwrite_sheet: Delete the contents of the sheet, then write to it.
675-
* overwrite_cells: Write directly to the named sheet
676-
without deleting the previous contents.
673+
* avoid: Create a new sheet with a different name.
674+
* replace: Delete the contents of the sheet before writing to it.
675+
* overwrite: Write directly to the named sheet
676+
without deleting the previous contents.
677+
* fail: raise a ValueError.
677678
678679
.. versionadded:: 1.3.0
679680
@@ -844,7 +845,7 @@ def __init__(
844845
datetime_format=None,
845846
mode: str = "w",
846847
storage_options: StorageOptions = None,
847-
if_exists: Optional[str] = None,
848+
if_sheet_exists: Optional[str] = None,
848849
**engine_kwargs,
849850
):
850851
# validate that this engine can handle the extension
@@ -879,17 +880,18 @@ def __init__(
879880

880881
self.mode = mode
881882

882-
if if_exists and "r+" not in mode:
883-
raise ValueError("if_exists is only valid in append mode (mode='a')")
884-
if if_exists is not None and if_exists not in {
885-
"new_sheet",
886-
"overwrite_sheet",
887-
"overwrite_cells",
883+
if if_sheet_exists and "r+" not in mode:
884+
raise ValueError("if_sheet_exists is only valid in append mode (mode='a')")
885+
if if_sheet_exists is not None and if_sheet_exists not in {
886+
"avoid",
887+
"replace",
888+
"overwrite",
889+
"fail",
888890
}:
889-
raise ValueError(f"'{if_exists}' is not valid for if_exists")
890-
if if_exists is None and "r+" in mode:
891-
if_exists = "new_sheet"
892-
self.if_exists = if_exists
891+
raise ValueError(f"'{if_sheet_exists}' is not valid for if_sheet_exists")
892+
if if_sheet_exists is None and "r+" in mode:
893+
if_sheet_exists = "avoid"
894+
self.if_sheet_exists = if_sheet_exists
893895

894896
def __fspath__(self):
895897
return getattr(self.handles.handle, "name", "")

pandas/io/excel/_openpyxl.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def __init__(
3737
engine=None,
3838
mode: str = "w",
3939
storage_options: StorageOptions = None,
40-
if_exists: Optional[str] = None,
40+
if_sheet_exists: Optional[str] = None,
4141
**engine_kwargs,
4242
):
4343
# Use the openpyxl module as the Excel writer.
@@ -47,7 +47,7 @@ def __init__(
4747
path,
4848
mode=mode,
4949
storage_options=storage_options,
50-
if_exists=if_exists,
50+
if_sheet_exists=if_sheet_exists,
5151
**engine_kwargs,
5252
)
5353

@@ -420,18 +420,22 @@ def write_cells(
420420

421421
if sheet_name in self.sheets:
422422
if "r+" in self.mode:
423-
if self.if_exists == "new_sheet":
423+
if self.if_sheet_exists == "avoid":
424424
wks = self.book.create_sheet()
425425
# openpyxl will create a name for the new sheet by appending digits
426426
wks.title = sheet_name
427427
self.sheets[wks.title] = wks
428-
elif self.if_exists == "overwrite_sheet":
428+
elif self.if_sheet_exists == "replace":
429429
wks = self.sheets[sheet_name]
430430
wks.delete_cols(1, wks.max_column)
431-
elif self.if_exists == "overwrite_cells" or self.if_exists is None:
431+
elif self.if_sheet_exists == "overwrite":
432432
wks = self.sheets[sheet_name]
433+
elif self.if_sheet_exists == "fail":
434+
raise ValueError(f"Sheet '{sheet_name}' already exists.")
433435
else:
434-
raise ValueError(f"'{self.if_exists}' is not valid for if_exists")
436+
raise ValueError(
437+
f"'{self.if_sheet_exists}' is not valid for if_sheet_exists"
438+
)
435439
else:
436440
wks = self.sheets[sheet_name]
437441
else:

pandas/tests/io/excel/test_openpyxl.py

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,23 +111,23 @@ def test_write_append_mode(ext, mode, expected):
111111

112112

113113
@pytest.mark.parametrize(
114-
"if_exists,num_sheets,expected",
114+
"if_sheet_exists,num_sheets,expected",
115115
[
116-
("new_sheet", 2, ["apple", "banana"]),
117-
("overwrite_sheet", 1, ["pear"]),
118-
("overwrite_cells", 1, ["pear", "banana"]),
116+
("avoid", 2, ["apple", "banana"]),
117+
(None, 2, ["apple", "banana"]),
118+
("replace", 1, ["pear"]),
119+
("overwrite", 1, ["pear", "banana"]),
119120
],
120121
)
121-
def test_if_exists_append_modes(ext, if_exists, num_sheets, expected):
122+
def test_if_sheet_exists_append_modes(ext, if_sheet_exists, num_sheets, expected):
122123
# GH 40230
123124
df1 = DataFrame({"fruit": ["apple", "banana"]})
124125
df2 = DataFrame({"fruit": ["pear"]})
125126

126127
with tm.ensure_clean(ext) as f:
127-
with pd.ExcelWriter(f, engine="openpyxl", mode="w") as writer:
128-
df1.to_excel(writer, sheet_name="foo", index=False)
128+
df1.to_excel(f, engine="openpyxl", sheet_name="foo", index=False)
129129
with pd.ExcelWriter(
130-
f, engine="openpyxl", mode="a", if_exists=if_exists
130+
f, engine="openpyxl", mode="a", if_sheet_exists=if_sheet_exists
131131
) as writer:
132132
df2.to_excel(writer, sheet_name="foo", index=False)
133133

@@ -144,16 +144,27 @@ def test_if_exists_append_modes(ext, if_exists, num_sheets, expected):
144144
wb.close()
145145

146146

147-
def test_if_exists_raises(ext):
148-
if_exists_msg = "if_exists is only valid in append mode (mode='a')"
149-
invalid_msg = "'invalid' is not valid for if_exists"
147+
def test_if_sheet_exists_raises(ext):
148+
mode_msg = "if_sheet_exists is only valid in append mode (mode='a')"
149+
invalid_msg = "'invalid' is not valid for if_sheet_exists"
150+
fail_msg = "Sheet 'foo' already exists."
151+
df = DataFrame({"fruit": ["pear"]})
150152

151153
with tm.ensure_clean(ext) as f:
152-
with pytest.raises(ValueError, match=re.escape(if_exists_msg)):
153-
ExcelWriter(f, engine="openpyxl", mode="w", if_exists="new_sheet")
154+
with pytest.raises(ValueError, match=re.escape(mode_msg)):
155+
ExcelWriter(f, engine="openpyxl", mode="w", if_sheet_exists="new_sheet")
156+
154157
with tm.ensure_clean(ext) as f:
155158
with pytest.raises(ValueError, match=invalid_msg):
156-
ExcelWriter(f, engine="openpyxl", mode="a", if_exists="invalid")
159+
ExcelWriter(f, engine="openpyxl", mode="a", if_sheet_exists="invalid")
160+
161+
with tm.ensure_clean(ext) as f:
162+
with pytest.raises(ValueError, match=fail_msg):
163+
df.to_excel(f, "foo", engine="openpyxl")
164+
with pd.ExcelWriter(
165+
f, engine="openpyxl", mode="a", if_sheet_exists="fail"
166+
) as writer:
167+
df.to_excel(writer, sheet_name="foo")
157168

158169

159170
def test_to_excel_with_openpyxl_engine(ext):

0 commit comments

Comments
 (0)