From de694e382c0afbfdd73b4b0634e2ec787013a06e Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Sun, 2 Nov 2025 15:27:50 -0800 Subject: [PATCH 1/2] BUG: copy.copy returning deep instead of shallow copy --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/core/generic.py | 4 ++-- pandas/core/indexes/base.py | 4 ++-- pandas/tests/generic/test_generic.py | 5 +++++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 12f522301e121..e2428f0e3d50e 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -1265,6 +1265,7 @@ Other - Bug in :meth:`Series.replace` and :meth:`DataFrame.replace` throwing ``ValueError`` when ``regex=True`` and all NA values. (:issue:`60688`) - Bug in :meth:`Series.to_string` when series contains complex floats with exponents (:issue:`60405`) - Bug in :meth:`read_csv` where chained fsspec TAR file and ``compression="infer"`` fails with ``tarfile.ReadError`` (:issue:`60028`) +- Bug when calling :py:func:`copy.copy` on a :class:`DataFrame` or :class:`Series` which would return a deep copy instead of a shallow copy (:issue:`?`) - Bug in Dataframe Interchange Protocol implementation was returning incorrect results for data buffers' associated dtype, for string and datetime columns (:issue:`54781`) - Bug in ``Series.list`` methods not preserving the original :class:`Index`. (:issue:`58425`) - Bug in ``Series.list`` methods not preserving the original name. (:issue:`60522`) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index b542ca1f431c3..735a59e5cfbb8 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -6680,8 +6680,8 @@ def copy(self, deep: bool = True) -> Self: ) @final - def __copy__(self, deep: bool = True) -> Self: - return self.copy(deep=deep) + def __copy__(self) -> Self: + return self.copy(deep=False) @final def __deepcopy__(self, memo=None) -> Self: diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 72f7a1e086b60..904de6a012671 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1413,8 +1413,8 @@ def copy( return new_index @final - def __copy__(self, **kwargs) -> Self: - return self.copy(**kwargs) + def __copy__(self) -> Self: + return self.copy(deep=False) @final def __deepcopy__(self, memo=None) -> Self: diff --git a/pandas/tests/generic/test_generic.py b/pandas/tests/generic/test_generic.py index b591b1b1092d4..ee6503b6929b6 100644 --- a/pandas/tests/generic/test_generic.py +++ b/pandas/tests/generic/test_generic.py @@ -307,6 +307,11 @@ def test_copy_and_deepcopy(self, frame_or_series, shape, func): assert obj_copy is not obj tm.assert_equal(obj_copy, obj) + def test_stdlib_copy_shallow_copies(self, frame_or_series): + obj = frame_or_series(range(3)) + obj_copy = copy(obj) + assert tm.shares_memory(obj, obj_copy) + class TestNDFrame: # tests that don't fit elsewhere From 712f34a20d100e92152e0d23ee5eb82baf6b6dd2 Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Mon, 3 Nov 2025 11:30:32 -0800 Subject: [PATCH 2/2] Add issue number --- doc/source/whatsnew/v3.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 8ba98dc9ccd05..26a9a6854b8c5 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -1268,7 +1268,6 @@ Other - Bug in :meth:`Series.replace` and :meth:`DataFrame.replace` throwing ``ValueError`` when ``regex=True`` and all NA values. (:issue:`60688`) - Bug in :meth:`Series.to_string` when series contains complex floats with exponents (:issue:`60405`) - Bug in :meth:`read_csv` where chained fsspec TAR file and ``compression="infer"`` fails with ``tarfile.ReadError`` (:issue:`60028`) -- Bug when calling :py:func:`copy.copy` on a :class:`DataFrame` or :class:`Series` which would return a deep copy instead of a shallow copy (:issue:`?`) - Bug in Dataframe Interchange Protocol implementation was returning incorrect results for data buffers' associated dtype, for string and datetime columns (:issue:`54781`) - Bug in ``Series.list`` methods not preserving the original :class:`Index`. (:issue:`58425`) - Bug in ``Series.list`` methods not preserving the original name. (:issue:`60522`) @@ -1276,6 +1275,7 @@ Other - Bug in ``divmod`` and ``rdivmod`` with :class:`DataFrame`, :class:`Series`, and :class:`Index` with ``bool`` dtypes failing to raise, which was inconsistent with ``__floordiv__`` behavior (:issue:`46043`) - Bug in printing a :class:`DataFrame` with a :class:`DataFrame` stored in :attr:`DataFrame.attrs` raised a ``ValueError`` (:issue:`60455`) - Bug in printing a :class:`Series` with a :class:`DataFrame` stored in :attr:`Series.attrs` raised a ``ValueError`` (:issue:`60568`) +- Bug when calling :py:func:`copy.copy` on a :class:`DataFrame` or :class:`Series` which would return a deep copy instead of a shallow copy (:issue:`62971`) - Deprecated the keyword ``check_datetimelike_compat`` in :meth:`testing.assert_frame_equal` and :meth:`testing.assert_series_equal` (:issue:`55638`) - Fixed bug in :meth:`Series.replace` and :meth:`DataFrame.replace` when trying to replace :class:`NA` values in a :class:`Float64Dtype` object with ``np.nan``; this now works with ``pd.set_option("mode.nan_is_na", False)`` and is irrelevant otherwise (:issue:`55127`) - Fixed bug in :meth:`Series.replace` and :meth:`DataFrame.replace` when trying to replace :class:`np.nan` values in a :class:`Int64Dtype` object with :class:`NA`; this is now a no-op with ``pd.set_option("mode.nan_is_na", False)`` and is irrelevant otherwise (:issue:`51237`)