From 862fb3115882a8f8549cac6f1580b7178075a7bf Mon Sep 17 00:00:00 2001 From: richard Date: Sat, 29 Nov 2025 22:32:31 -0500 Subject: [PATCH 1/6] DEPR: Copy-on-Write option --- pandas/core/config_init.py | 15 +++++++++++---- pandas/tests/copy_view/test_copy_deprecation.py | 7 +++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index 83015f4007793..aedaf22ade685 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -408,12 +408,11 @@ def is_terminal() -> bool: cf.register_option("sim_interactive", False, tc_sim_interactive_doc) -# TODO better name? copy_on_write_doc = """ : bool - Use new copy-view behaviour using Copy-on-Write. Defaults to False, - unless overridden by the 'PANDAS_COPY_ON_WRITE' environment variable - (if set to "1" for True, needs to be set before pandas is imported). + Use new copy-view behaviour using Copy-on-Write. No longer used, + pandas now always uses Copy-on-Write behavior. This option will + be removed in pandas 4.0. """ @@ -902,3 +901,11 @@ def register_converter_cb(key: str) -> None: # GH#59502 cf.deprecate_option("future.no_silent_downcasting", Pandas4Warning) +cf.deprecate_option( + "mode.copy_on_write", + Pandas4Warning, + msg=( + "Copy-on-Write can no longer be disabled, setting to False has no impact. " + "This option will be removed in pandas 4.0." + ), +) diff --git a/pandas/tests/copy_view/test_copy_deprecation.py b/pandas/tests/copy_view/test_copy_deprecation.py index 67ee804a755fb..2d97748e27a3f 100644 --- a/pandas/tests/copy_view/test_copy_deprecation.py +++ b/pandas/tests/copy_view/test_copy_deprecation.py @@ -89,3 +89,10 @@ def test_copy_deprecation_merge_concat(): Pandas4Warning, match="copy", check_stacklevel=False ): concat([df, df], copy=False) + + +@pytest.mark.parametrize("value", [False, True, "warn"]) +def test_copy_on_write_deprecation_option(value): + msg = "Copy-on-Write can no longer be disabled" + with tm.assert_produces_warning(Pandas4Warning, match=msg): + pd.set_option("mode.copy_on_write", value) From f8c2cab924cd14a338d0079361aa453efee698aa Mon Sep 17 00:00:00 2001 From: richard Date: Sat, 29 Nov 2025 22:34:15 -0500 Subject: [PATCH 2/6] whatsnew --- doc/source/whatsnew/v3.0.0.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 222790cfbef6c..ddc76ecb32a83 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -117,6 +117,9 @@ process in more detail. `PDEP-7: Consistent copy/view semantics in pandas with Copy-on-Write `__ +Setting the option ``mode.copy_on_write`` no longer has any impact. The option is deprecated +and will be removed in pandas 4.0. + .. _whatsnew_300.enhancements.col: ``pd.col`` syntax can now be used in :meth:`DataFrame.assign` and :meth:`DataFrame.loc` From 0e1294ee0cfd3600f6aa95d15c614a6aeadf809d Mon Sep 17 00:00:00 2001 From: Richard Shadrach Date: Sun, 30 Nov 2025 09:10:29 -0500 Subject: [PATCH 3/6] Update docstring --- pandas/errors/__init__.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/pandas/errors/__init__.py b/pandas/errors/__init__.py index f4864518ae5e6..64ecd4b0c5aa1 100644 --- a/pandas/errors/__init__.py +++ b/pandas/errors/__init__.py @@ -668,7 +668,7 @@ class ChainedAssignmentError(Warning): """ Warning raised when trying to set using chained assignment. - When the ``mode.copy_on_write`` option is enabled, chained assignment can + With Copy-on-Write now always enabled, chained assignment can never work. In such a situation, we are always setting into a temporary object that is the result of an indexing operation (getitem), which under Copy-on-Write always behaves as a copy. Thus, assigning through a chain @@ -677,18 +677,11 @@ class ChainedAssignmentError(Warning): For more information on Copy-on-Write, see :ref:`the user guide`. - See Also - -------- - options.mode.copy_on_write : Global setting for enabling or disabling - Copy-on-Write behavior. - Examples -------- - >>> pd.options.mode.copy_on_write = True >>> df = pd.DataFrame({"A": [1, 1, 1, 2, 2]}, columns=["A"]) >>> df["A"][0:3] = 10 # doctest: +SKIP ... # ChainedAssignmentError: ... - >>> pd.options.mode.copy_on_write = False """ From bdc9c1c847c18769fa2abe0bd5f0b2b97780de84 Mon Sep 17 00:00:00 2001 From: Richard Shadrach Date: Sun, 30 Nov 2025 09:17:23 -0500 Subject: [PATCH 4/6] Ignore missing see-also --- ci/code_checks.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index a5b5ce8ef3cb1..068851731f9ed 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -72,6 +72,7 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.Series.dt PR01" `# Accessors are implemented as classes, but we do not document the Parameters section` \ -i "pandas.Period.freq GL08" \ -i "pandas.Period.ordinal GL08" \ + -i "pandas.erros.ChainedAssignmentError SA01" \ -i "pandas.errors.IncompatibleFrequency SA01,SS06,EX01" \ -i "pandas.api.extensions.ExtensionArray.value_counts EX01,RT03,SA01" \ -i "pandas.api.typing.DataFrameGroupBy.plot PR02" \ From f7c74ea34705ce9910787a95accd9eaeef7c9b23 Mon Sep 17 00:00:00 2001 From: Richard Shadrach Date: Sun, 30 Nov 2025 10:03:44 -0500 Subject: [PATCH 5/6] Fixup --- ci/code_checks.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/code_checks.sh b/ci/code_checks.sh index 068851731f9ed..7a95ed0eef2b2 100755 --- a/ci/code_checks.sh +++ b/ci/code_checks.sh @@ -72,7 +72,7 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then -i "pandas.Series.dt PR01" `# Accessors are implemented as classes, but we do not document the Parameters section` \ -i "pandas.Period.freq GL08" \ -i "pandas.Period.ordinal GL08" \ - -i "pandas.erros.ChainedAssignmentError SA01" \ + -i "pandas.errors.ChainedAssignmentError SA01" \ -i "pandas.errors.IncompatibleFrequency SA01,SS06,EX01" \ -i "pandas.api.extensions.ExtensionArray.value_counts EX01,RT03,SA01" \ -i "pandas.api.typing.DataFrameGroupBy.plot PR02" \ From 97cd13bfa031e3980ddcb074b619c66abeb2cd5e Mon Sep 17 00:00:00 2001 From: richard Date: Sun, 30 Nov 2025 16:37:36 -0500 Subject: [PATCH 6/6] Avoid side-effects in test --- pandas/tests/copy_view/test_copy_deprecation.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/tests/copy_view/test_copy_deprecation.py b/pandas/tests/copy_view/test_copy_deprecation.py index 2d97748e27a3f..acc87787dbe0a 100644 --- a/pandas/tests/copy_view/test_copy_deprecation.py +++ b/pandas/tests/copy_view/test_copy_deprecation.py @@ -94,5 +94,7 @@ def test_copy_deprecation_merge_concat(): @pytest.mark.parametrize("value", [False, True, "warn"]) def test_copy_on_write_deprecation_option(value): msg = "Copy-on-Write can no longer be disabled" - with tm.assert_produces_warning(Pandas4Warning, match=msg): - pd.set_option("mode.copy_on_write", value) + # stacklevel points to contextlib due to use of context manager. + with tm.assert_produces_warning(Pandas4Warning, match=msg, check_stacklevel=False): + with pd.option_context("mode.copy_on_write", value): + pass